summaryrefslogtreecommitdiff
path: root/zebra/kernel_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/kernel_netlink.c')
-rw-r--r--zebra/kernel_netlink.c69
1 files changed, 45 insertions, 24 deletions
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 84c15a2a92..d84b0c1325 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -38,7 +38,6 @@
#include "lib_errors.h"
#include "hash.h"
-//#include "zebra/zserv.h"
#include "zebra/zebra_router.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
@@ -48,6 +47,7 @@
#include "zebra/rt_netlink.h"
#include "zebra/if_netlink.h"
#include "zebra/rule_netlink.h"
+#include "zebra/netconf_netlink.h"
#include "zebra/zebra_errors.h"
#ifndef SO_RCVBUFFORCE
@@ -108,6 +108,8 @@ static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"},
{RTM_NEWNEXTHOP, "RTM_NEWNEXTHOP"},
{RTM_DELNEXTHOP, "RTM_DELNEXTHOP"},
{RTM_GETNEXTHOP, "RTM_GETNEXTHOP"},
+ {RTM_NEWNETCONF, "RTM_NEWNETCONF"},
+ {RTM_DELNETCONF, "RTM_DELNETCONF"},
{0}};
static const struct message rtproto_str[] = {
@@ -153,7 +155,6 @@ static const struct message rttype_str[] = {{RTN_UNSPEC, "none"},
{0}};
extern struct thread_master *master;
-extern uint32_t nl_rcvbufsize;
extern struct zebra_privs_t zserv_privs;
@@ -259,12 +260,11 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize)
/* Try force option (linux >= 2.6.14) and fall back to normal set */
frr_with_privs(&zserv_privs) {
ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE,
- &nl_rcvbufsize,
- sizeof(nl_rcvbufsize));
+ &rcvbufsize, sizeof(rcvbufsize));
}
if (ret < 0)
- ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF,
- &nl_rcvbufsize, sizeof(nl_rcvbufsize));
+ ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
+ sizeof(rcvbufsize));
if (ret < 0) {
flog_err_sys(EC_LIB_SOCKET,
"Can't set %s receive buffer size: %s", nl->name,
@@ -373,6 +373,8 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
/* Messages handled in the dplane thread */
case RTM_NEWADDR:
case RTM_DELADDR:
+ case RTM_NEWNETCONF:
+ case RTM_DELNETCONF:
return 0;
default:
@@ -407,7 +409,12 @@ static int dplane_netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
case RTM_DELADDR:
return netlink_interface_addr_dplane(h, ns_id, startup);
- /* TODO */
+ case RTM_NEWNETCONF:
+ case RTM_DELNETCONF:
+ return netlink_netconf_change(h, ns_id, startup);
+
+ /* TODO -- other messages for the dplane socket and pthread */
+
case RTM_NEWLINK:
case RTM_DELLINK:
@@ -418,7 +425,7 @@ static int dplane_netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
return 0;
}
-static int kernel_read(struct thread *thread)
+static void kernel_read(struct thread *thread)
{
struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread);
struct zebra_dplane_info dp_info;
@@ -431,8 +438,6 @@ static int kernel_read(struct thread *thread)
thread_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock,
&zns->t_netlink);
-
- return 0;
}
/*
@@ -458,8 +463,8 @@ int kernel_dplane_read(struct zebra_dplane_info *info)
* then the normal course of operations). We are intentionally
* allowing some messages from ourselves through
* ( I'm looking at you Interface based netlink messages )
- * so that we only had to write one way to handle incoming
- * address add/delete changes.
+ * so that we only have to write one way to handle incoming
+ * address add/delete and xxxNETCONF changes.
*/
static void netlink_install_filter(int sock, uint32_t pid, uint32_t dplane_pid)
{
@@ -475,7 +480,8 @@ static void netlink_install_filter(int sock, uint32_t pid, uint32_t dplane_pid)
* if (nlmsg_pid == pid ||
* nlmsg_pid == dplane_pid) {
* if (the incoming nlmsg_type ==
- * RTM_NEWADDR | RTM_DELADDR)
+ * RTM_NEWADDR || RTM_DELADDR || RTM_NEWNETCONF ||
+ * RTM_DELNETCONF)
* keep this message
* else
* skip this message
@@ -494,7 +500,7 @@ static void netlink_install_filter(int sock, uint32_t pid, uint32_t dplane_pid)
/*
* 2: Compare to dplane pid
*/
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htonl(dplane_pid), 0, 4),
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htonl(dplane_pid), 0, 6),
/*
* 3: Load the nlmsg_type into BPF register
*/
@@ -503,17 +509,27 @@ static void netlink_install_filter(int sock, uint32_t pid, uint32_t dplane_pid)
/*
* 4: Compare to RTM_NEWADDR
*/
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_NEWADDR), 2, 0),
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_NEWADDR), 4, 0),
/*
* 5: Compare to RTM_DELADDR
*/
- BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_DELADDR), 1, 0),
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_DELADDR), 3, 0),
/*
- * 6: This is the end state of we want to skip the
+ * 6: Compare to RTM_NEWNETCONF
+ */
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_NEWNETCONF), 2,
+ 0),
+ /*
+ * 7: Compare to RTM_DELNETCONF
+ */
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_DELNETCONF), 1,
+ 0),
+ /*
+ * 8: This is the end state of we want to skip the
* message
*/
BPF_STMT(BPF_RET | BPF_K, 0),
- /* 7: This is the end state of we want to keep
+ /* 9: This is the end state of we want to keep
* the message
*/
BPF_STMT(BPF_RET | BPF_K, 0xffff),
@@ -1472,6 +1488,7 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth,
case DPLANE_OP_INTF_ADDR_ADD:
case DPLANE_OP_INTF_ADDR_DEL:
+ case DPLANE_OP_INTF_NETCONFIG:
case DPLANE_OP_NONE:
return FRR_NETLINK_ERROR;
}
@@ -1599,7 +1616,11 @@ void kernel_init(struct zebra_ns *zns)
dplane_groups = (RTMGRP_LINK |
RTMGRP_IPV4_IFADDR |
- RTMGRP_IPV6_IFADDR);
+ RTMGRP_IPV6_IFADDR |
+ ((uint32_t) 1 << (RTNLGRP_IPV4_NETCONF - 1)) |
+ ((uint32_t) 1 << (RTNLGRP_IPV6_NETCONF - 1)) |
+ ((uint32_t) 1 << (RTNLGRP_MPLS_NETCONF - 1)));
+
snprintf(zns->netlink.name, sizeof(zns->netlink.name),
"netlink-listen (NS %u)", zns->ns_id);
@@ -1709,11 +1730,11 @@ void kernel_init(struct zebra_ns *zns)
errno);
/* Set receive buffer size if it's set from command line */
- if (nl_rcvbufsize) {
- netlink_recvbuf(&zns->netlink, nl_rcvbufsize);
- netlink_recvbuf(&zns->netlink_cmd, nl_rcvbufsize);
- netlink_recvbuf(&zns->netlink_dplane_out, nl_rcvbufsize);
- netlink_recvbuf(&zns->netlink_dplane_in, nl_rcvbufsize);
+ if (rcvbufsize) {
+ netlink_recvbuf(&zns->netlink, rcvbufsize);
+ netlink_recvbuf(&zns->netlink_cmd, rcvbufsize);
+ netlink_recvbuf(&zns->netlink_dplane_out, rcvbufsize);
+ netlink_recvbuf(&zns->netlink_dplane_in, rcvbufsize);
}
/* Set filter for inbound sockets, to exclude events we've generated