diff options
-rw-r--r-- | net/core/rtnetlink.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e8488c7b092c..b442d35bbc8b 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -2011,6 +2011,33 @@ nla_put_failure: | |||
2011 | return -EMSGSIZE; | 2011 | return -EMSGSIZE; |
2012 | } | 2012 | } |
2013 | 2013 | ||
2014 | static inline size_t rtnl_fdb_nlmsg_size(void) | ||
2015 | { | ||
2016 | return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN); | ||
2017 | } | ||
2018 | |||
2019 | static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type) | ||
2020 | { | ||
2021 | struct net *net = dev_net(dev); | ||
2022 | struct sk_buff *skb; | ||
2023 | int err = -ENOBUFS; | ||
2024 | |||
2025 | skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC); | ||
2026 | if (!skb) | ||
2027 | goto errout; | ||
2028 | |||
2029 | err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF); | ||
2030 | if (err < 0) { | ||
2031 | kfree_skb(skb); | ||
2032 | goto errout; | ||
2033 | } | ||
2034 | |||
2035 | rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); | ||
2036 | return; | ||
2037 | errout: | ||
2038 | rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); | ||
2039 | } | ||
2040 | |||
2014 | static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 2041 | static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
2015 | { | 2042 | { |
2016 | struct net *net = sock_net(skb->sk); | 2043 | struct net *net = sock_net(skb->sk); |
@@ -2067,8 +2094,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2067 | err = dev->netdev_ops->ndo_fdb_add(ndm, dev, addr, | 2094 | err = dev->netdev_ops->ndo_fdb_add(ndm, dev, addr, |
2068 | nlh->nlmsg_flags); | 2095 | nlh->nlmsg_flags); |
2069 | 2096 | ||
2070 | if (!err) | 2097 | if (!err) { |
2098 | rtnl_fdb_notify(dev, addr, RTM_NEWNEIGH); | ||
2071 | ndm->ndm_flags &= ~NTF_SELF; | 2099 | ndm->ndm_flags &= ~NTF_SELF; |
2100 | } | ||
2072 | } | 2101 | } |
2073 | out: | 2102 | out: |
2074 | return err; | 2103 | return err; |
@@ -2125,8 +2154,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
2125 | if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) { | 2154 | if ((ndm->ndm_flags & NTF_SELF) && dev->netdev_ops->ndo_fdb_del) { |
2126 | err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr); | 2155 | err = dev->netdev_ops->ndo_fdb_del(ndm, dev, addr); |
2127 | 2156 | ||
2128 | if (!err) | 2157 | if (!err) { |
2158 | rtnl_fdb_notify(dev, addr, RTM_DELNEIGH); | ||
2129 | ndm->ndm_flags &= ~NTF_SELF; | 2159 | ndm->ndm_flags &= ~NTF_SELF; |
2160 | } | ||
2130 | } | 2161 | } |
2131 | out: | 2162 | out: |
2132 | return err; | 2163 | return err; |