diff options
Diffstat (limited to 'zebra/kernel_netlink.c')
| -rw-r--r-- | zebra/kernel_netlink.c | 69 |
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 |
