diff options
| author | Mark Stapp <mjs.ietf@gmail.com> | 2021-07-14 13:06:41 -0400 | 
|---|---|---|
| committer | Mark Stapp <mjs.ietf@gmail.com> | 2021-09-14 11:07:30 -0400 | 
| commit | d166308be009537caf733dbe0b55fae7553726a1 (patch) | |
| tree | 93e644d11cd23a1107e7292a6e6db33e900408e9 /zebra/kernel_netlink.c | |
| parent | e7c2c1985ce6f7e974d580d7d00f59cc11f225ac (diff) | |
zebra: use the dataplane to read netlink intf addr changes
Read incoming interface address change notifications in the
dplane pthread; enqueue the events to the main pthread
for processing. This is netlink-only for now - the bsd
kernel socket path remains unchanged.
Signed-off-by: Mark Stapp <mjs.ietf@gmail.com>
Diffstat (limited to 'zebra/kernel_netlink.c')
| -rw-r--r-- | zebra/kernel_netlink.c | 77 | 
1 files changed, 60 insertions, 17 deletions
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index f50fd74ac1..602bdc1dc5 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -324,6 +324,10 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups,  	return ret;  } +/* + * Dispatch an incoming netlink message; used by the zebra main pthread's + * netlink event reader. + */  static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,  				     int startup)  { @@ -345,10 +349,6 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,  		return netlink_link_change(h, ns_id, startup);  	case RTM_DELLINK:  		return netlink_link_change(h, ns_id, startup); -	case RTM_NEWADDR: -		return netlink_interface_addr(h, ns_id, startup); -	case RTM_DELADDR: -		return netlink_interface_addr(h, ns_id, startup);  	case RTM_NEWNEIGH:  	case RTM_DELNEIGH:  	case RTM_GETNEIGH: @@ -361,6 +361,12 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,  		return netlink_nexthop_change(h, ns_id, startup);  	case RTM_DELNEXTHOP:  		return netlink_nexthop_change(h, ns_id, startup); + +	/* Messages handled in the dplane thread */ +	case RTM_NEWADDR: +	case RTM_DELADDR: +		return 0; +  	default:  		/*  		 * If we have received this message then @@ -378,6 +384,32 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,  	return 0;  } +/* + * Dispatch an incoming netlink message; used by the dataplane pthread's + * netlink event reader code. + */ +static int dplane_netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, +					    int startup) +{ +	/* +	 * Dispatch the incoming messages that the dplane pthread handles +	 */ +	switch (h->nlmsg_type) { +	case RTM_NEWADDR: +	case RTM_DELADDR: +		return netlink_interface_addr_dplane(h, ns_id, startup); + +	/* TODO */ +	case RTM_NEWLINK: +	case RTM_DELLINK: + +	default: +		break; +	} + +	return 0; +} +  static int kernel_read(struct thread *thread)  {  	struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread); @@ -388,7 +420,7 @@ static int kernel_read(struct thread *thread)  	netlink_parse_info(netlink_information_fetch, &zns->netlink, &dp_info,  			   5, 0); -	zns->t_netlink = NULL; +  	thread_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock,  			&zns->t_netlink); @@ -396,6 +428,17 @@ static int kernel_read(struct thread *thread)  }  /* + * Called by the dplane pthread to read incoming OS messages and dispatch them. + */ +int kernel_dplane_read(struct zebra_dplane_info *info) +{ +	netlink_parse_info(dplane_netlink_information_fetch, &info->nls, info, +			   5, 0); + +	return 0; +} + +/*   * Filter out messages from self that occur on listener socket,   * caused by our actions on the command socket(s)   * @@ -476,9 +519,8 @@ static void netlink_install_filter(int sock, uint32_t pid, uint32_t dplane_pid)  			     safe_strerror(errno));  } -void netlink_parse_rtattr_flags(struct rtattr **tb, int max, -				struct rtattr *rta, int len, -				unsigned short flags) +void netlink_parse_rtattr_flags(struct rtattr **tb, int max, struct rtattr *rta, +				int len, unsigned short flags)  {  	unsigned short type; @@ -800,8 +842,7 @@ static int netlink_recv_msg(const struct nlsock *nl, struct msghdr msg,   * ignored, -1 otherwise.   */  static int netlink_parse_error(const struct nlsock *nl, struct nlmsghdr *h, -			       const struct zebra_dplane_info *zns, -			       bool startup) +			       bool is_cmd, bool startup)  {  	struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(h);  	int errnum = err->error; @@ -834,7 +875,7 @@ static int netlink_parse_error(const struct nlsock *nl, struct nlmsghdr *h,  	}  	/* Deal with errors that occur because of races in link handling. */ -	if (zns->is_cmd +	if (is_cmd  	    && ((msg_type == RTM_DELROUTE  		 && (-errnum == ENODEV || -errnum == ESRCH))  		|| (msg_type == RTM_NEWROUTE @@ -853,7 +894,7 @@ static int netlink_parse_error(const struct nlsock *nl, struct nlmsghdr *h,  	 * do not log these as an error.  	 */  	if (msg_type == RTM_DELNEIGH -	    || (zns->is_cmd && msg_type == RTM_NEWROUTE +	    || (is_cmd && msg_type == RTM_NEWROUTE  		&& (-errnum == ESRCH || -errnum == ENETUNREACH))) {  		/*  		 * This is known to happen in some situations, don't log as @@ -925,8 +966,9 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),  			/* Error handling. */  			if (h->nlmsg_type == NLMSG_ERROR) { -				int err = netlink_parse_error(nl, h, zns, -							      startup); +				int err = netlink_parse_error( +					nl, h, zns->is_cmd, startup); +  				if (err == 1) {  					if (!(h->nlmsg_flags & NLM_F_MULTI))  						return 0; @@ -938,8 +980,8 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),  			/* OK we got netlink message. */  			if (IS_ZEBRA_DEBUG_KERNEL)  				zlog_debug( -					"netlink_parse_info: %s type %s(%u), len=%d, seq=%u, pid=%u", -					nl->name, +					"%s: %s type %s(%u), len=%d, seq=%u, pid=%u", +					__func__, nl->name,  					nl_msg_type_to_str(h->nlmsg_type),  					h->nlmsg_type, h->nlmsg_len,  					h->nlmsg_seq, h->nlmsg_pid); @@ -1141,7 +1183,8 @@ static int nl_batch_read_resp(struct nl_batch *bth)  		}  		if (h->nlmsg_type == NLMSG_ERROR) { -			int err = netlink_parse_error(nl, h, bth->zns, 0); +			int err = netlink_parse_error(nl, h, bth->zns->is_cmd, +						      false);  			if (err == -1)  				dplane_ctx_set_status(  | 
