aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorVlad Yasevich <vyasevic@redhat.com>2013-02-13 07:00:18 -0500
committerDavid S. Miller <davem@davemloft.net>2013-02-13 19:42:16 -0500
commit1690be63a27b20ae65c792729a44f5970561ffa4 (patch)
treec0c86bc471e24207ee61b544c8683d84fc43d105 /net/core
parentb0e9a30dd669a844bb4f74515f8bcd307018ffd0 (diff)
bridge: Add vlan support to static neighbors
When a user adds bridge neighbors, allow him to specify VLAN id. If the VLAN id is not specified, the neighbor will be added for VLANs currently in the ports filter list. If no VLANs are configured on the port, we use vlan 0 and only add 1 entry. Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> Acked-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/rtnetlink.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f3a112ec86d5..d8aa20f6a46e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2119,13 +2119,17 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2119{ 2119{
2120 struct net *net = sock_net(skb->sk); 2120 struct net *net = sock_net(skb->sk);
2121 struct ndmsg *ndm; 2121 struct ndmsg *ndm;
2122 struct nlattr *llattr; 2122 struct nlattr *tb[NDA_MAX+1];
2123 struct net_device *dev; 2123 struct net_device *dev;
2124 int err = -EINVAL; 2124 int err = -EINVAL;
2125 __u8 *addr; 2125 __u8 *addr;
2126 2126
2127 if (nlmsg_len(nlh) < sizeof(*ndm)) 2127 if (!capable(CAP_NET_ADMIN))
2128 return -EINVAL; 2128 return -EPERM;
2129
2130 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
2131 if (err < 0)
2132 return err;
2129 2133
2130 ndm = nlmsg_data(nlh); 2134 ndm = nlmsg_data(nlh);
2131 if (ndm->ndm_ifindex == 0) { 2135 if (ndm->ndm_ifindex == 0) {
@@ -2139,13 +2143,17 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2139 return -ENODEV; 2143 return -ENODEV;
2140 } 2144 }
2141 2145
2142 llattr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_LLADDR); 2146 if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
2143 if (llattr == NULL || nla_len(llattr) != ETH_ALEN) { 2147 pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid address\n");
2144 pr_info("PF_BRIGDE: RTM_DELNEIGH with invalid address\n"); 2148 return -EINVAL;
2149 }
2150
2151 addr = nla_data(tb[NDA_LLADDR]);
2152 if (!is_valid_ether_addr(addr)) {
2153 pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ether address\n");
2145 return -EINVAL; 2154 return -EINVAL;
2146 } 2155 }
2147 2156
2148 addr = nla_data(llattr);
2149 err = -EOPNOTSUPP; 2157 err = -EOPNOTSUPP;
2150 2158
2151 /* Support fdb on master device the net/bridge default case */ 2159 /* Support fdb on master device the net/bridge default case */
@@ -2155,7 +2163,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2155 const struct net_device_ops *ops = br_dev->netdev_ops; 2163 const struct net_device_ops *ops = br_dev->netdev_ops;
2156 2164
2157 if (ops->ndo_fdb_del) 2165 if (ops->ndo_fdb_del)
2158 err = ops->ndo_fdb_del(ndm, dev, addr); 2166 err = ops->ndo_fdb_del(ndm, tb, dev, addr);
2159 2167
2160 if (err) 2168 if (err)
2161 goto out; 2169 goto out;
@@ -2165,7 +2173,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2165 2173
2166 /* Embedded bridge, macvlan, and any other device support */ 2174 /* Embedded bridge, macvlan, and any other device support */
2167 if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) { 2175 if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) {
2168 err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr); 2176 err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr);
2169 2177
2170 if (!err) { 2178 if (!err) {
2171 rtnl_fdb_notify(dev, addr, RTM_DELNEIGH); 2179 rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);