diff options
author | meurisa <alexander.meuris@technicolor.com> | 2019-04-12 09:56:28 +0200 |
---|---|---|
committer | Hans Dedecker <dedeckeh@gmail.com> | 2019-04-15 22:31:38 +0200 |
commit | 08989e46b9030671ce57b8872538d40e2ddcbbe0 (patch) | |
tree | c0119c3ca57b572adcfa6462d34411a6e0c2f0ac /system-linux.c | |
parent | bfd4de3666901070d805878e55b02417fef6277c (diff) |
interface: add neighbor config support
The neighbor or neighbor6 network section makes neighbours
configurable via UCI or proto shell handlers. It allows to
install neighbor proxy entries or static neighbor entries
The neighbor or neighbor6 section has the following types:
interface : declares the logical OpenWrt interface
ipaddr : the ip address of the neighbor
mac : the mac address of the neighbor
proxy : specifies whether the neighbor ia a proxy
entry (can be 1 or 0)
router : specifies whether the neighbor is a router
(can be 1 or 0)
Signed-off-by: Alexander Meuris <meurisalexander@gmail.com>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Diffstat (limited to 'system-linux.c')
-rw-r--r-- | system-linux.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/system-linux.c b/system-linux.c index 82e9928..6a0105e 100644 --- a/system-linux.c +++ b/system-linux.c @@ -31,6 +31,7 @@ #include <netinet/in.h> #include <linux/rtnetlink.h> +#include <linux/neighbour.h> #include <linux/sockios.h> #include <linux/ip.h> #include <linux/if_addr.h> @@ -1023,8 +1024,8 @@ void system_if_clear_state(struct device *dev) { static char buf[256]; char *bridge; - device_set_ifindex(dev, system_if_resolve(dev)); + if (dev->external || !dev->ifindex) return; @@ -1046,6 +1047,8 @@ void system_if_clear_state(struct device *dev) system_if_clear_entries(dev, RTM_GETADDR, AF_INET); system_if_clear_entries(dev, RTM_GETROUTE, AF_INET6); system_if_clear_entries(dev, RTM_GETADDR, AF_INET6); + system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET); + system_if_clear_entries(dev, RTM_GETNEIGH, AF_INET6); system_set_disable_ipv6(dev, "0"); } @@ -1930,6 +1933,51 @@ int system_del_address(struct device *dev, struct device_addr *addr) return system_addr(dev, addr, RTM_DELADDR); } +static int system_neigh(struct device *dev, struct device_neighbor *neighbor, int cmd) +{ + int alen = ((neighbor->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16; + unsigned int flags = 0; + struct ndmsg ndm = { + .ndm_family = (alen == 4) ? AF_INET : AF_INET6, + .ndm_ifindex = dev->ifindex, + .ndm_state = NUD_PERMANENT, + .ndm_flags = (neighbor->proxy ? NTF_PROXY : 0) | (neighbor->router ? NTF_ROUTER : 0), + }; + struct nl_msg *msg; + + if (!dev) + return 1; + + if (cmd == RTM_NEWNEIGH) + flags |= NLM_F_CREATE | NLM_F_REPLACE; + + msg = nlmsg_alloc_simple(cmd, flags); + + if (!msg) + return -1; + + nlmsg_append(msg, &ndm, sizeof(ndm), 0); + + nla_put(msg, NDA_DST, alen, &neighbor->addr); + if (neighbor->flags & DEVNEIGH_MAC) + nla_put(msg, NDA_LLADDR, sizeof(neighbor->macaddr), &neighbor->macaddr); + + + return system_rtnl_call(msg); +} + +int system_add_neighbor(struct device *dev, struct device_neighbor *neighbor) +{ + return system_neigh(dev, neighbor, RTM_NEWNEIGH); +} + +int system_del_neighbor(struct device *dev, struct device_neighbor *neighbor) +{ + int rval = system_neigh(dev, neighbor, RTM_DELNEIGH); + netifd_log_message(L_NOTICE,"return delete %d", rval); + return rval; +} + static int system_rt(struct device *dev, struct device_route *route, int cmd) { int alen = ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4) ? 4 : 16; |