lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 5 Oct 2011 21:06:54 +0200
From:	Kevin Wilson <wkevils@...il.com>
To:	netdev@...r.kernel.org
Subject: Re: [PATCH 5/7] bridge: allow creating/deleting fdb entries via netlink

Hello all,
I would appreciate if someone can elaborate about "bridge extensions
to iproute2" mentioned here.
I downloaded latest iproute2 git tree and did not find it there.
googling for it did not gave much info about it.
I will appreciate if someone can tell  who develop it, what is the
status, site, repository tree, etc.

rgs,
Kevin

On Tue, Apr 5, 2011 at 3:03 AM, Stephen Hemminger <shemminger@...tta.com> wrote:
> Use RTM_NEWNEIGH and RTM_DELNEIGH to allow updating of entries
> in bridge forwarding table. This allows manipulating static entries
> which is not possible with existing tools.
>
> Example (using bridge extensions to iproute2)
>   # br fdb add 00:02:03:04:05:06 dev eth0
>
> Signed-off-by: Stephen Hemminger <shemminger@...tta.com>
>
> ---
>  net/bridge/br_fdb.c     |  139 ++++++++++++++++++++++++++++++++++++++++++++++++
>  net/bridge/br_netlink.c |    3 +
>  net/bridge/br_private.h |    2
>  3 files changed, 144 insertions(+)
>
> --- a/net/bridge/br_fdb.c       2011-03-22 10:25:00.329008182 -0700
> +++ b/net/bridge/br_fdb.c       2011-03-22 10:25:01.057042585 -0700
> @@ -555,3 +555,142 @@ skip:
>
>        return skb->len;
>  }
> +
> +/* Create new static fdb entry */
> +static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
> +                        __u16 state)
> +{
> +       struct net_bridge *br = source->br;
> +       struct hlist_head *head = &br->hash[br_mac_hash(addr)];
> +       struct net_bridge_fdb_entry *fdb;
> +
> +       fdb = fdb_find(head, addr);
> +       if (fdb)
> +               return -EEXIST;
> +
> +       fdb = fdb_create(head, source, addr);
> +       if (!fdb)
> +               return -ENOMEM;
> +
> +       if (state & NUD_PERMANENT)
> +               fdb->is_local = fdb->is_static = 1;
> +       else if (state & NUD_NOARP)
> +               fdb->is_static = 1;
> +       return 0;
> +}
> +
> +/* Add new permanent fdb entry with RTM_NEWNEIGH */
> +int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
> +{
> +       struct net *net = sock_net(skb->sk);
> +       struct ndmsg *ndm;
> +       struct nlattr *tb[NDA_MAX+1];
> +       struct net_device *dev;
> +       struct net_bridge_port *p;
> +       const __u8 *addr;
> +       int err;
> +
> +       ASSERT_RTNL();
> +       err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
> +       if (err < 0)
> +               return err;
> +
> +       ndm = nlmsg_data(nlh);
> +       if (ndm->ndm_ifindex == 0) {
> +               pr_info("bridge: RTM_NEWNEIGH with invalid ifindex\n");
> +               return -EINVAL;
> +       }
> +
> +       dev = __dev_get_by_index(net, ndm->ndm_ifindex);
> +       if (dev == NULL) {
> +               pr_info("bridge: RTM_NEWNEIGH with unknown ifindex\n");
> +               return -ENODEV;
> +       }
> +
> +       if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
> +               pr_info("bridge: RTM_NEWNEIGH with invalid address\n");
> +               return -EINVAL;
> +       }
> +
> +       addr = nla_data(tb[NDA_LLADDR]);
> +       if (!is_valid_ether_addr(addr)) {
> +               pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
> +               return -EINVAL;
> +       }
> +
> +       p = br_port_get_rtnl(dev);
> +       if (p == NULL) {
> +               pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
> +                       dev->name);
> +               return -EINVAL;
> +       }
> +
> +       spin_lock_bh(&p->br->hash_lock);
> +       err = fdb_add_entry(p, addr, ndm->ndm_state);
> +       spin_unlock_bh(&p->br->hash_lock);
> +
> +       return err;
> +}
> +
> +static int fdb_delete_by_addr(struct net_bridge_port *p, const u8 *addr)
> +{
> +       struct net_bridge *br = p->br;
> +       struct hlist_head *head = &br->hash[br_mac_hash(addr)];
> +       struct net_bridge_fdb_entry *fdb;
> +
> +       fdb = fdb_find(head, addr);
> +       if (!fdb)
> +               return -ENOENT;
> +
> +       fdb_delete(fdb);
> +       return 0;
> +}
> +
> +/* Remove neighbor entry with RTM_DELNEIGH */
> +int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
> +{
> +       struct net *net = sock_net(skb->sk);
> +       struct ndmsg *ndm;
> +       struct net_bridge_port *p;
> +       struct nlattr *llattr;
> +       const __u8 *addr;
> +       struct net_device *dev;
> +       int err;
> +
> +       ASSERT_RTNL();
> +       if (nlmsg_len(nlh) < sizeof(*ndm))
> +               return -EINVAL;
> +
> +       ndm = nlmsg_data(nlh);
> +       if (ndm->ndm_ifindex == 0) {
> +               pr_info("bridge: RTM_DELNEIGH with invalid ifindex\n");
> +               return -EINVAL;
> +       }
> +
> +       dev = __dev_get_by_index(net, ndm->ndm_ifindex);
> +       if (dev == NULL) {
> +               pr_info("bridge: RTM_DELNEIGH with unknown ifindex\n");
> +               return -ENODEV;
> +       }
> +
> +       llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR);
> +       if (llattr == NULL || nla_len(llattr) != ETH_ALEN) {
> +               pr_info("bridge: RTM_DELNEIGH with invalid address\n");
> +               return -EINVAL;
> +       }
> +
> +       addr = nla_data(llattr);
> +
> +       p = br_port_get_rtnl(dev);
> +       if (p == NULL) {
> +               pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
> +                       dev->name);
> +               return -EINVAL;
> +       }
> +
> +       spin_lock_bh(&p->br->hash_lock);
> +       err = fdb_delete_by_addr(p, addr);
> +       spin_unlock_bh(&p->br->hash_lock);
> +
> +       return err;
> +}
> --- a/net/bridge/br_netlink.c   2011-03-22 10:25:00.329008182 -0700
> +++ b/net/bridge/br_netlink.c   2011-03-22 10:25:01.057042585 -0700
> @@ -196,6 +196,9 @@ int __init br_netlink_init(void)
>
>        /* Only the first call to __rtnl_register can fail */
>        __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL);
> +
> +       __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL);
> +       __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL);
>        __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump);
>
>        return 0;
> --- a/net/bridge/br_private.h   2011-03-22 10:25:00.329008182 -0700
> +++ b/net/bridge/br_private.h   2011-03-22 10:25:01.057042585 -0700
> @@ -355,6 +355,8 @@ extern void br_fdb_update(struct net_bri
>                          struct net_bridge_port *source,
>                          const unsigned char *addr);
>  extern int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb);
> +extern int br_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
> +extern int br_fdb_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
>
>  /* br_forward.c */
>  extern void br_deliver(const struct net_bridge_port *to,
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ