summaryrefslogtreecommitdiffhomepage
path: root/system-linux.c
diff options
context:
space:
mode:
authormeurisa <alexander.meuris@technicolor.com>2019-04-12 09:56:28 +0200
committerHans Dedecker <dedeckeh@gmail.com>2019-04-15 22:31:38 +0200
commit08989e46b9030671ce57b8872538d40e2ddcbbe0 (patch)
treec0119c3ca57b572adcfa6462d34411a6e0c2f0ac /system-linux.c
parentbfd4de3666901070d805878e55b02417fef6277c (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.c50
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;