diff options
Diffstat (limited to 'zebra/kernel_netlink.c')
| -rw-r--r-- | zebra/kernel_netlink.c | 1246 | 
1 files changed, 610 insertions, 636 deletions
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 9faf925522..f3ca12abf3 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -54,13 +54,13 @@  #endif /* MSG_TRUNC */  #ifndef NLMSG_TAIL -#define NLMSG_TAIL(nmsg) \ -        ((struct rtattr *) (((u_char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#define NLMSG_TAIL(nmsg)                                                       \ +	((struct rtattr *)(((u_char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))  #endif  #ifndef RTA_TAIL -#define RTA_TAIL(rta) \ -        ((struct rtattr *) (((u_char *) (rta)) + RTA_ALIGN((rta)->rta_len))) +#define RTA_TAIL(rta)                                                          \ +	((struct rtattr *)(((u_char *)(rta)) + RTA_ALIGN((rta)->rta_len)))  #endif  #ifndef RTNL_FAMILY_IP6MR @@ -71,374 +71,342 @@  #define RTPROT_MROUTED 17  #endif -static const struct message nlmsg_str[] = { -  {RTM_NEWROUTE, "RTM_NEWROUTE"}, -  {RTM_DELROUTE, "RTM_DELROUTE"}, -  {RTM_GETROUTE, "RTM_GETROUTE"}, -  {RTM_NEWLINK,  "RTM_NEWLINK"}, -  {RTM_DELLINK,  "RTM_DELLINK"}, -  {RTM_GETLINK,  "RTM_GETLINK"}, -  {RTM_NEWADDR,  "RTM_NEWADDR"}, -  {RTM_DELADDR,  "RTM_DELADDR"}, -  {RTM_GETADDR,  "RTM_GETADDR"}, -  {RTM_NEWNEIGH, "RTM_NEWNEIGH"}, -  {RTM_DELNEIGH, "RTM_DELNEIGH"}, -  {RTM_GETNEIGH, "RTM_GETNEIGH"}, -  { 0 } -}; +static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"}, +					   {RTM_DELROUTE, "RTM_DELROUTE"}, +					   {RTM_GETROUTE, "RTM_GETROUTE"}, +					   {RTM_NEWLINK, "RTM_NEWLINK"}, +					   {RTM_DELLINK, "RTM_DELLINK"}, +					   {RTM_GETLINK, "RTM_GETLINK"}, +					   {RTM_NEWADDR, "RTM_NEWADDR"}, +					   {RTM_DELADDR, "RTM_DELADDR"}, +					   {RTM_GETADDR, "RTM_GETADDR"}, +					   {RTM_NEWNEIGH, "RTM_NEWNEIGH"}, +					   {RTM_DELNEIGH, "RTM_DELNEIGH"}, +					   {RTM_GETNEIGH, "RTM_GETNEIGH"}, +					   {0}};  static const struct message rtproto_str[] = { -  {RTPROT_REDIRECT, "redirect"}, -  {RTPROT_KERNEL,   "kernel"}, -  {RTPROT_BOOT,     "boot"}, -  {RTPROT_STATIC,   "static"}, -  {RTPROT_GATED,    "GateD"}, -  {RTPROT_RA,       "router advertisement"}, -  {RTPROT_MRT,      "MRT"}, -  {RTPROT_ZEBRA,    "Zebra"}, +	{RTPROT_REDIRECT, "redirect"}, {RTPROT_KERNEL, "kernel"}, +	{RTPROT_BOOT, "boot"},	 {RTPROT_STATIC, "static"}, +	{RTPROT_GATED, "GateD"},       {RTPROT_RA, "router advertisement"}, +	{RTPROT_MRT, "MRT"},	   {RTPROT_ZEBRA, "Zebra"},  #ifdef RTPROT_BIRD -  {RTPROT_BIRD,     "BIRD"}, +	{RTPROT_BIRD, "BIRD"},  #endif /* RTPROT_BIRD */ -  {RTPROT_MROUTED,  "mroute"}, -  { 0 } -}; - -static const struct message family_str[] = { -  {AF_INET,           "ipv4"}, -  {AF_INET6,          "ipv6"}, -  {AF_BRIDGE,         "bridge"}, -  {RTNL_FAMILY_IPMR,  "ipv4MR"}, -  {RTNL_FAMILY_IP6MR, "ipv6MR"}, -  { 0 } -}; - -static const struct message rttype_str[] = { -  {RTN_UNICAST,   "unicast"}, -  {RTN_MULTICAST, "multicast"}, -  { 0 } -}; +	{RTPROT_MROUTED, "mroute"},    {0}}; + +static const struct message family_str[] = {{AF_INET, "ipv4"}, +					    {AF_INET6, "ipv6"}, +					    {AF_BRIDGE, "bridge"}, +					    {RTNL_FAMILY_IPMR, "ipv4MR"}, +					    {RTNL_FAMILY_IP6MR, "ipv6MR"}, +					    {0}}; + +static const struct message rttype_str[] = {{RTN_UNICAST, "unicast"}, +					    {RTN_MULTICAST, "multicast"}, +					    {0}};  extern struct thread_master *master;  extern u_int32_t nl_rcvbufsize;  extern struct zebra_privs_t zserv_privs; -int -netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h, -                     ns_id_t ns_id, int startup) +int netlink_talk_filter(struct sockaddr_nl *snl, struct nlmsghdr *h, +			ns_id_t ns_id, int startup)  { -  zlog_warn ("netlink_talk: ignoring message type 0x%04x NS %u", h->nlmsg_type, -             ns_id); -  return 0; +	zlog_warn("netlink_talk: ignoring message type 0x%04x NS %u", +		  h->nlmsg_type, ns_id); +	return 0;  } -static int -netlink_recvbuf (struct nlsock *nl, uint32_t newsize) +static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize)  { -  u_int32_t oldsize; -  socklen_t newlen = sizeof(newsize); -  socklen_t oldlen = sizeof(oldsize); -  int ret; - -  ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen); -  if (ret < 0) -    { -      zlog_err("Can't get %s receive buffer size: %s", nl->name, -               safe_strerror(errno)); -      return -1; -    } - -  /* Try force option (linux >= 2.6.14) and fall back to normal set */ -  if ( zserv_privs.change (ZPRIVS_RAISE) ) -    zlog_err ("routing_socket: Can't raise privileges"); -  ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize, -		   sizeof(nl_rcvbufsize)); -  if ( zserv_privs.change (ZPRIVS_LOWER) ) -    zlog_err ("routing_socket: Can't lower privileges"); -  if (ret < 0) -     ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize, -		      sizeof(nl_rcvbufsize)); -  if (ret < 0) -    { -      zlog_err("Can't set %s receive buffer size: %s", nl->name, -               safe_strerror(errno)); -      return -1; -    } - -  ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen); -  if (ret < 0) -    { -      zlog_err("Can't get %s receive buffer size: %s", nl->name, -               safe_strerror(errno)); -      return -1; -    } - -  zlog_info("Setting netlink socket receive buffer size: %u -> %u", oldsize, -            newsize); -  return 0; +	u_int32_t oldsize; +	socklen_t newlen = sizeof(newsize); +	socklen_t oldlen = sizeof(oldsize); +	int ret; + +	ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen); +	if (ret < 0) { +		zlog_err("Can't get %s receive buffer size: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	/* Try force option (linux >= 2.6.14) and fall back to normal set */ +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("routing_socket: Can't raise privileges"); +	ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize, +			 sizeof(nl_rcvbufsize)); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("routing_socket: Can't lower privileges"); +	if (ret < 0) +		ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, +				 &nl_rcvbufsize, sizeof(nl_rcvbufsize)); +	if (ret < 0) { +		zlog_err("Can't set %s receive buffer size: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen); +	if (ret < 0) { +		zlog_err("Can't get %s receive buffer size: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	zlog_info("Setting netlink socket receive buffer size: %u -> %u", +		  oldsize, newsize); +	return 0;  }  /* Make socket for Linux netlink interface. */ -static int -netlink_socket (struct nlsock *nl, unsigned long groups, ns_id_t ns_id) +static int netlink_socket(struct nlsock *nl, unsigned long groups, +			  ns_id_t ns_id)  { -  int ret; -  struct sockaddr_nl snl; -  int sock; -  int namelen; -  int save_errno; - -  if (zserv_privs.change (ZPRIVS_RAISE)) -    { -      zlog_err("Can't raise privileges"); -      return -1; -    } - -  sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); -  if (sock < 0) -    { -      zlog_err("Can't open %s socket: %s", nl->name, safe_strerror(errno)); -      return -1; -    } - -  memset (&snl, 0, sizeof snl); -  snl.nl_family = AF_NETLINK; -  snl.nl_groups = groups; - -  /* Bind the socket to the netlink structure for anything. */ -  ret = bind (sock, (struct sockaddr *) &snl, sizeof snl); -  save_errno = errno; -  if (zserv_privs.change (ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  if (ret < 0) -    { -      zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name, -               snl.nl_groups, safe_strerror(save_errno)); -      close (sock); -      return -1; -    } - -  /* multiple netlink sockets will have different nl_pid */ -  namelen = sizeof snl; -  ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen); -  if (ret < 0 || namelen != sizeof snl) -    { -      zlog_err("Can't get %s socket name: %s", nl->name, safe_strerror(errno)); -      close (sock); -      return -1; -    } - -  nl->snl = snl; -  nl->sock = sock; -  return ret; +	int ret; +	struct sockaddr_nl snl; +	int sock; +	int namelen; +	int save_errno; + +	if (zserv_privs.change(ZPRIVS_RAISE)) { +		zlog_err("Can't raise privileges"); +		return -1; +	} + +	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); +	if (sock < 0) { +		zlog_err("Can't open %s socket: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	memset(&snl, 0, sizeof snl); +	snl.nl_family = AF_NETLINK; +	snl.nl_groups = groups; + +	/* Bind the socket to the netlink structure for anything. */ +	ret = bind(sock, (struct sockaddr *)&snl, sizeof snl); +	save_errno = errno; +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (ret < 0) { +		zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name, +			 snl.nl_groups, safe_strerror(save_errno)); +		close(sock); +		return -1; +	} + +	/* multiple netlink sockets will have different nl_pid */ +	namelen = sizeof snl; +	ret = getsockname(sock, (struct sockaddr *)&snl, (socklen_t *)&namelen); +	if (ret < 0 || namelen != sizeof snl) { +		zlog_err("Can't get %s socket name: %s", nl->name, +			 safe_strerror(errno)); +		close(sock); +		return -1; +	} + +	nl->snl = snl; +	nl->sock = sock; +	return ret;  } -static int -netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h, -                           ns_id_t ns_id, int startup) +static int netlink_information_fetch(struct sockaddr_nl *snl, +				     struct nlmsghdr *h, ns_id_t ns_id, +				     int startup)  { -  /* JF: Ignore messages that aren't from the kernel */ -  if ( snl->nl_pid != 0 ) -    { -      zlog_err("Ignoring message from pid %u", snl->nl_pid); -      return 0; -    } - -  switch (h->nlmsg_type) -    { -    case RTM_NEWROUTE: -      return netlink_route_change (snl, h, ns_id, startup); -      break; -    case RTM_DELROUTE: -      return netlink_route_change (snl, h, ns_id, startup); -      break; -    case RTM_NEWLINK: -      return netlink_link_change (snl, h, ns_id, startup); -      break; -    case RTM_DELLINK: -      return netlink_link_change (snl, h, ns_id, startup); -      break; -    case RTM_NEWADDR: -      return netlink_interface_addr (snl, h, ns_id, startup); -      break; -    case RTM_DELADDR: -      return netlink_interface_addr (snl, h, ns_id, startup); -      break; -    default: -      zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type, -                 ns_id); -      break; -    } -  return 0; +	/* JF: Ignore messages that aren't from the kernel */ +	if (snl->nl_pid != 0) { +		zlog_err("Ignoring message from pid %u", snl->nl_pid); +		return 0; +	} + +	switch (h->nlmsg_type) { +	case RTM_NEWROUTE: +		return netlink_route_change(snl, h, ns_id, startup); +		break; +	case RTM_DELROUTE: +		return netlink_route_change(snl, h, ns_id, startup); +		break; +	case RTM_NEWLINK: +		return netlink_link_change(snl, h, ns_id, startup); +		break; +	case RTM_DELLINK: +		return netlink_link_change(snl, h, ns_id, startup); +		break; +	case RTM_NEWADDR: +		return netlink_interface_addr(snl, h, ns_id, startup); +		break; +	case RTM_DELADDR: +		return netlink_interface_addr(snl, h, ns_id, startup); +		break; +	default: +		zlog_warn("Unknown netlink nlmsg_type %d vrf %u\n", +			  h->nlmsg_type, ns_id); +		break; +	} +	return 0;  } -static int -kernel_read (struct thread *thread) +static int kernel_read(struct thread *thread)  { -  struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG (thread); -  netlink_parse_info (netlink_information_fetch, &zns->netlink, zns, 5, 0); -  zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns, -                                     zns->netlink.sock); +	struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread); +	netlink_parse_info(netlink_information_fetch, &zns->netlink, zns, 5, 0); +	zns->t_netlink = thread_add_read(zebrad.master, kernel_read, zns, +					 zns->netlink.sock); -  return 0; +	return 0;  }  /* Filter out messages from self that occur on listener socket,   * caused by our actions on the command socket   */ -static void netlink_install_filter (int sock, __u32 pid) +static void netlink_install_filter(int sock, __u32 pid)  { -  struct sock_filter filter[] = { -    /* 0: ldh [4]	          */ -    BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)), -    /* 1: jeq 0x18 jt 3 jf 6  */ -    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0), -    /* 2: jeq 0x19 jt 3 jf 6  */ -    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3), -    /* 3: ldw [12]		  */ -    BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)), -    /* 4: jeq XX  jt 5 jf 6   */ -    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1), -    /* 5: ret 0    (skip)     */ -    BPF_STMT(BPF_RET|BPF_K, 0), -    /* 6: ret 0xffff (keep)   */ -    BPF_STMT(BPF_RET|BPF_K, 0xffff), -  }; - -  struct sock_fprog prog = { -    .len = array_size(filter), -    .filter = filter, -  }; - -  if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0) -    zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno)); +	struct sock_filter filter[] = { +		/* 0: ldh [4]	          */ +		BPF_STMT(BPF_LD | BPF_ABS | BPF_H, +			 offsetof(struct nlmsghdr, nlmsg_type)), +		/* 1: jeq 0x18 jt 3 jf 6  */ +		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_NEWROUTE), 1, 0), +		/* 2: jeq 0x19 jt 3 jf 6  */ +		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_DELROUTE), 0, 3), +		/* 3: ldw [12]		  */ +		BPF_STMT(BPF_LD | BPF_ABS | BPF_W, +			 offsetof(struct nlmsghdr, nlmsg_pid)), +		/* 4: jeq XX  jt 5 jf 6   */ +		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htonl(pid), 0, 1), +		/* 5: ret 0    (skip)     */ +		BPF_STMT(BPF_RET | BPF_K, 0), +		/* 6: ret 0xffff (keep)   */ +		BPF_STMT(BPF_RET | BPF_K, 0xffff), +	}; + +	struct sock_fprog prog = { +		.len = array_size(filter), .filter = filter, +	}; + +	if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) +	    < 0) +		zlog_warn("Can't install socket filter: %s\n", +			  safe_strerror(errno));  } -void -netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta, -                      int len) +void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, +			  int len)  { -  while (RTA_OK (rta, len)) -    { -      if (rta->rta_type <= max) -        tb[rta->rta_type] = rta; -      rta = RTA_NEXT (rta, len); -    } +	while (RTA_OK(rta, len)) { +		if (rta->rta_type <= max) +			tb[rta->rta_type] = rta; +		rta = RTA_NEXT(rta, len); +	}  } -int -addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type, -	   void *data, unsigned int alen) +int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, void *data, +	      unsigned int alen)  { -  int len; -  struct rtattr *rta; +	int len; +	struct rtattr *rta; -  len = RTA_LENGTH (alen); +	len = RTA_LENGTH(alen); -  if (NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len) > maxlen) -    return -1; +	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) +		return -1; -  rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len)); -  rta->rta_type = type; -  rta->rta_len = len; +	rta = (struct rtattr *)(((char *)n) + NLMSG_ALIGN(n->nlmsg_len)); +	rta->rta_type = type; +	rta->rta_len = len; -  if (data) -    memcpy (RTA_DATA (rta), data, alen); -  else -    assert (alen == 0); +	if (data) +		memcpy(RTA_DATA(rta), data, alen); +	else +		assert(alen == 0); -  n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len); +	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); -  return 0; +	return 0;  } -int -rta_addattr_l (struct rtattr *rta, unsigned int maxlen, int type, -	       void *data, unsigned int alen) +int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type, void *data, +		  unsigned int alen)  { -  unsigned int len; -  struct rtattr *subrta; +	unsigned int len; +	struct rtattr *subrta; -  len = RTA_LENGTH (alen); +	len = RTA_LENGTH(alen); -  if (RTA_ALIGN (rta->rta_len) + RTA_ALIGN (len) > maxlen) -    return -1; +	if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) +		return -1; -  subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len)); -  subrta->rta_type = type; -  subrta->rta_len = len; +	subrta = (struct rtattr *)(((char *)rta) + RTA_ALIGN(rta->rta_len)); +	subrta->rta_type = type; +	subrta->rta_len = len; -  if (data) -    memcpy (RTA_DATA (subrta), data, alen); -  else -    assert (alen == 0); +	if (data) +		memcpy(RTA_DATA(subrta), data, alen); +	else +		assert(alen == 0); -  rta->rta_len = NLMSG_ALIGN (rta->rta_len) + RTA_ALIGN (len); +	rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len); -  return 0; +	return 0;  } -int -addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data) +int addattr32(struct nlmsghdr *n, unsigned int maxlen, int type, int data)  { -  return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t)); +	return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t));  } -struct rtattr * -addattr_nest(struct nlmsghdr *n, int maxlen, int type) +struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type)  { -  struct rtattr *nest = NLMSG_TAIL(n); +	struct rtattr *nest = NLMSG_TAIL(n); -  addattr_l(n, maxlen, type, NULL, 0); -  return nest; +	addattr_l(n, maxlen, type, NULL, 0); +	return nest;  } -int -addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest) +int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest)  { -  nest->rta_len = (u_char *)NLMSG_TAIL(n) - (u_char *)nest; -  return n->nlmsg_len; +	nest->rta_len = (u_char *)NLMSG_TAIL(n) - (u_char *)nest; +	return n->nlmsg_len;  } -struct rtattr * -rta_nest(struct rtattr *rta, int maxlen, int type) +struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type)  { -  struct rtattr *nest = RTA_TAIL(rta); +	struct rtattr *nest = RTA_TAIL(rta); -  rta_addattr_l(rta, maxlen, type, NULL, 0); -  return nest; +	rta_addattr_l(rta, maxlen, type, NULL, 0); +	return nest;  } -int -rta_nest_end(struct rtattr *rta, struct rtattr *nest) +int rta_nest_end(struct rtattr *rta, struct rtattr *nest)  { -  nest->rta_len = (u_char *)RTA_TAIL(rta) - (u_char *)nest; -  return rta->rta_len; +	nest->rta_len = (u_char *)RTA_TAIL(rta) - (u_char *)nest; +	return rta->rta_len;  } -const char * -nl_msg_type_to_str (uint16_t msg_type) +const char *nl_msg_type_to_str(uint16_t msg_type)  { -  return lookup_msg (nlmsg_str, msg_type, ""); +	return lookup_msg(nlmsg_str, msg_type, "");  } -const char * -nl_rtproto_to_str (u_char rtproto) +const char *nl_rtproto_to_str(u_char rtproto)  { -  return lookup_msg (rtproto_str, rtproto, ""); +	return lookup_msg(rtproto_str, rtproto, "");  } -const char * -nl_family_to_str (u_char family) +const char *nl_family_to_str(u_char family)  { -  return lookup_msg (family_str, family, ""); +	return lookup_msg(family_str, family, "");  } -const char * -nl_rttype_to_str (u_char rttype) +const char *nl_rttype_to_str(u_char rttype)  { -  return lookup_msg (rttype_str, rttype, ""); +	return lookup_msg(rttype_str, rttype, "");  }  /* @@ -454,192 +422,210 @@ nl_rttype_to_str (u_char rttype)   * startup -> Are we reading in under startup conditions? passed to   *            the filter.   */ -int -netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, -                                   ns_id_t, int), -                    struct nlsock *nl, struct zebra_ns *zns, int count, int startup) +int netlink_parse_info(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *, +				     ns_id_t, int), +		       struct nlsock *nl, struct zebra_ns *zns, int count, +		       int startup)  { -  int status; -  int ret = 0; -  int error; -  int read_in = 0; - -  while (1) -    { -      char buf[NL_PKT_BUF_SIZE]; -      struct iovec iov = { -        .iov_base = buf, -        .iov_len = sizeof buf -      }; -      struct sockaddr_nl snl; -      struct msghdr msg = { -        .msg_name = (void *) &snl, -        .msg_namelen = sizeof snl, -        .msg_iov = &iov, -        .msg_iovlen = 1 -      }; -      struct nlmsghdr *h; - -      if (count && read_in >= count) -        return 0; - -      status = recvmsg (nl->sock, &msg, 0); -      if (status < 0) -        { -          if (errno == EINTR) -            continue; -          if (errno == EWOULDBLOCK || errno == EAGAIN) -            break; -          zlog_err("%s recvmsg overrun: %s", nl->name, safe_strerror(errno)); -          /* -           *  In this case we are screwed. -           *  There is no good way to -           *  recover zebra at this point. -           */ -          exit (-1); -          continue; -        } - -      if (status == 0) -        { -          zlog_err("%s EOF", nl->name); -          return -1; -        } - -      if (msg.msg_namelen != sizeof snl) -        { -          zlog_err("%s sender address length error: length %d", nl->name, -                   msg.msg_namelen); -          return -1; -        } - -      if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) -        { -          zlog_debug("%s: << netlink message dump [recv]", __func__); -          zlog_hexdump(&msg, sizeof(msg)); -        } - -      read_in++; -      for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status); -           h = NLMSG_NEXT (h, status)) -        { -          /* Finish of reading. */ -          if (h->nlmsg_type == NLMSG_DONE) -            return ret; - -          /* Error handling. */ -          if (h->nlmsg_type == NLMSG_ERROR) -            { -              struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h); -	      int errnum = err->error; -	      int msg_type = err->msg.nlmsg_type; - -              /* If the error field is zero, then this is an ACK */ -              if (err->error == 0) -                { -                  if (IS_ZEBRA_DEBUG_KERNEL) -                    { -                      zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u", -                                 __FUNCTION__, nl->name, -		                 nl_msg_type_to_str (err->msg.nlmsg_type), -                                 err->msg.nlmsg_type, err->msg.nlmsg_seq, -                                 err->msg.nlmsg_pid); -                    } - -                  /* return if not a multipart message, otherwise continue */ -                  if (!(h->nlmsg_flags & NLM_F_MULTI)) -                    return 0; -                  continue; -                } - -              if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr))) -                { -                  zlog_err("%s error: message truncated", nl->name); -                  return -1; -                } - -              /* Deal with errors that occur because of races in link handling */ -	      if (nl == &zns->netlink_cmd -		  && ((msg_type == RTM_DELROUTE && -		       (-errnum == ENODEV || -errnum == ESRCH)) -		      || (msg_type == RTM_NEWROUTE && -			  (-errnum == ENETDOWN || -errnum == EEXIST)))) -		{ -		  if (IS_ZEBRA_DEBUG_KERNEL) -		    zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u", -				nl->name, safe_strerror (-errnum), -				nl_msg_type_to_str (msg_type), -				msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); -		  return 0; +	int status; +	int ret = 0; +	int error; +	int read_in = 0; + +	while (1) { +		char buf[NL_PKT_BUF_SIZE]; +		struct iovec iov = {.iov_base = buf, .iov_len = sizeof buf}; +		struct sockaddr_nl snl; +		struct msghdr msg = {.msg_name = (void *)&snl, +				     .msg_namelen = sizeof snl, +				     .msg_iov = &iov, +				     .msg_iovlen = 1}; +		struct nlmsghdr *h; + +		if (count && read_in >= count) +			return 0; + +		status = recvmsg(nl->sock, &msg, 0); +		if (status < 0) { +			if (errno == EINTR) +				continue; +			if (errno == EWOULDBLOCK || errno == EAGAIN) +				break; +			zlog_err("%s recvmsg overrun: %s", nl->name, +				 safe_strerror(errno)); +			/* +			 *  In this case we are screwed. +			 *  There is no good way to +			 *  recover zebra at this point. +			 */ +			exit(-1); +			continue; +		} + +		if (status == 0) { +			zlog_err("%s EOF", nl->name); +			return -1; +		} + +		if (msg.msg_namelen != sizeof snl) { +			zlog_err("%s sender address length error: length %d", +				 nl->name, msg.msg_namelen); +			return -1; +		} + +		if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) { +			zlog_debug("%s: << netlink message dump [recv]", +				   __func__); +			zlog_hexdump(&msg, sizeof(msg)); +		} + +		read_in++; +		for (h = (struct nlmsghdr *)buf; +		     NLMSG_OK(h, (unsigned int)status); +		     h = NLMSG_NEXT(h, status)) { +			/* Finish of reading. */ +			if (h->nlmsg_type == NLMSG_DONE) +				return ret; + +			/* Error handling. */ +			if (h->nlmsg_type == NLMSG_ERROR) { +				struct nlmsgerr *err = +					(struct nlmsgerr *)NLMSG_DATA(h); +				int errnum = err->error; +				int msg_type = err->msg.nlmsg_type; + +				/* If the error field is zero, then this is an +				 * ACK */ +				if (err->error == 0) { +					if (IS_ZEBRA_DEBUG_KERNEL) { +						zlog_debug( +							"%s: %s ACK: type=%s(%u), seq=%u, pid=%u", +							__FUNCTION__, nl->name, +							nl_msg_type_to_str( +								err->msg.nlmsg_type), +							err->msg.nlmsg_type, +							err->msg.nlmsg_seq, +							err->msg.nlmsg_pid); +					} + +					/* return if not a multipart message, +					 * otherwise continue */ +					if (!(h->nlmsg_flags & NLM_F_MULTI)) +						return 0; +					continue; +				} + +				if (h->nlmsg_len +				    < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { +					zlog_err("%s error: message truncated", +						 nl->name); +					return -1; +				} + +				/* Deal with errors that occur because of races +				 * in link handling */ +				if (nl == &zns->netlink_cmd +				    && ((msg_type == RTM_DELROUTE +					 && (-errnum == ENODEV +					     || -errnum == ESRCH)) +					|| (msg_type == RTM_NEWROUTE +					    && (-errnum == ENETDOWN +						|| -errnum == EEXIST)))) { +					if (IS_ZEBRA_DEBUG_KERNEL) +						zlog_debug( +							"%s: error: %s type=%s(%u), seq=%u, pid=%u", +							nl->name, +							safe_strerror(-errnum), +							nl_msg_type_to_str( +								msg_type), +							msg_type, +							err->msg.nlmsg_seq, +							err->msg.nlmsg_pid); +					return 0; +				} + +				/* We see RTM_DELNEIGH when shutting down an +				 * interface with an IPv4 +				 * link-local.  The kernel should have already +				 * deleted the neighbor +				 * so do not log these as an error. +				 */ +				if (msg_type == RTM_DELNEIGH +				    || (nl == &zns->netlink_cmd +					&& msg_type == RTM_NEWROUTE +					&& (-errnum == ESRCH +					    || -errnum == ENETUNREACH))) { +					/* This is known to happen in some +					 * situations, don't log +					 * as error. +					 */ +					if (IS_ZEBRA_DEBUG_KERNEL) +						zlog_debug( +							"%s error: %s, type=%s(%u), seq=%u, pid=%u", +							nl->name, +							safe_strerror(-errnum), +							nl_msg_type_to_str( +								msg_type), +							msg_type, +							err->msg.nlmsg_seq, +							err->msg.nlmsg_pid); +				} else +					zlog_err( +						"%s error: %s, type=%s(%u), seq=%u, pid=%u", +						nl->name, +						safe_strerror(-errnum), +						nl_msg_type_to_str(msg_type), +						msg_type, err->msg.nlmsg_seq, +						err->msg.nlmsg_pid); + +				return -1; +			} + +			/* 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, +					nl_msg_type_to_str(h->nlmsg_type), +					h->nlmsg_type, h->nlmsg_len, +					h->nlmsg_seq, h->nlmsg_pid); + +			/* skip unsolicited messages originating from command +			 * socket +			 * linux sets the originators port-id for {NEW|DEL}ADDR +			 * messages, +			 * so this has to be checked here. */ +			if (nl != &zns->netlink_cmd +			    && h->nlmsg_pid == zns->netlink_cmd.snl.nl_pid +			    && (h->nlmsg_type != RTM_NEWADDR +				&& h->nlmsg_type != RTM_DELADDR)) { +				if (IS_ZEBRA_DEBUG_KERNEL) +					zlog_debug( +						"netlink_parse_info: %s packet comes from %s", +						zns->netlink_cmd.name, +						nl->name); +				continue; +			} + +			error = (*filter)(&snl, h, zns->ns_id, startup); +			if (error < 0) { +				zlog_err("%s filter function error", nl->name); +				ret = error; +			}  		} -              /* We see RTM_DELNEIGH when shutting down an interface with an IPv4 -               * link-local.  The kernel should have already deleted the neighbor -               * so do not log these as an error. -               */ -              if (msg_type == RTM_DELNEIGH || -                  (nl == &zns->netlink_cmd && msg_type == RTM_NEWROUTE && -                   (-errnum == ESRCH || -errnum == ENETUNREACH))) -		{ -                  /* This is known to happen in some situations, don't log -                   * as error. -                   */ -		  if (IS_ZEBRA_DEBUG_KERNEL) -	            zlog_debug ("%s error: %s, type=%s(%u), seq=%u, pid=%u", -                                nl->name, safe_strerror (-errnum), -                                nl_msg_type_to_str (msg_type), -                                msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); -                } -              else -	        zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u", -			nl->name, safe_strerror (-errnum), -                        nl_msg_type_to_str (msg_type), -			msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); - -              return -1; -            } - -          /* 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, -                       nl_msg_type_to_str (h->nlmsg_type), h->nlmsg_type, -                       h->nlmsg_len, h->nlmsg_seq, h->nlmsg_pid); - -          /* skip unsolicited messages originating from command socket -           * linux sets the originators port-id for {NEW|DEL}ADDR messages, -           * so this has to be checked here. */ -          if (nl != &zns->netlink_cmd -              && h->nlmsg_pid == zns->netlink_cmd.snl.nl_pid -              && (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)) -            { -              if (IS_ZEBRA_DEBUG_KERNEL) -                zlog_debug ("netlink_parse_info: %s packet comes from %s", -                            zns->netlink_cmd.name, nl->name); -              continue; -            } - -          error = (*filter) (&snl, h, zns->ns_id, startup); -          if (error < 0) -            { -              zlog_err("%s filter function error", nl->name); -              ret = error; -            } -        } - -      /* After error care. */ -      if (msg.msg_flags & MSG_TRUNC) -        { -          zlog_err("%s error: message truncated", nl->name); -          continue; -        } -      if (status) -        { -          zlog_err("%s error: data remnant size %d", nl->name, status); -          return -1; -        } -    } -  return ret; +		/* After error care. */ +		if (msg.msg_flags & MSG_TRUNC) { +			zlog_err("%s error: message truncated", nl->name); +			continue; +		} +		if (status) { +			zlog_err("%s error: data remnant size %d", nl->name, +				 status); +			return -1; +		} +	} +	return ret;  }  /* @@ -655,178 +641,166 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,   * startup  -> Are we reading in under startup conditions   *             This is passed through eventually to filter.   */ -int -netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, -                             ns_id_t, int startup), -              struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, int startup) +int netlink_talk(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *, ns_id_t, +			       int startup), +		 struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, +		 int startup)  { -  int status; -  struct sockaddr_nl snl; -  struct iovec iov = { -    .iov_base = (void *) n, -    .iov_len = n->nlmsg_len -  }; -  struct msghdr msg = { -    .msg_name = (void *) &snl, -    .msg_namelen = sizeof snl, -    .msg_iov = &iov, -    .msg_iovlen = 1, -  }; -  int save_errno; - -  memset (&snl, 0, sizeof snl); -  snl.nl_family = AF_NETLINK; - -  n->nlmsg_seq = ++nl->seq; - -  /* Request an acknowledgement by setting NLM_F_ACK */ -  n->nlmsg_flags |= NLM_F_ACK; - -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("netlink_talk: %s type %s(%u), len=%d seq=%u flags 0x%x", -               nl->name, -               nl_msg_type_to_str (n->nlmsg_type), n->nlmsg_type, -               n->nlmsg_len, n->nlmsg_seq, n->nlmsg_flags); - -  /* Send message to netlink interface. */ -  if (zserv_privs.change (ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  status = sendmsg (nl->sock, &msg, 0); -  save_errno = errno; -  if (zserv_privs.change (ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) -    { -      zlog_debug("%s: >> netlink message dump [sent]", __func__); -      zlog_hexdump(&msg, sizeof(msg)); -    } - -  if (status < 0) -    { -      zlog_err("netlink_talk sendmsg() error: %s", safe_strerror(save_errno)); -      return -1; -    } - - -  /* -   * Get reply from netlink socket. -   * The reply should either be an acknowlegement or an error. -   */ -  return netlink_parse_info (filter, nl, zns, 0, startup); +	int status; +	struct sockaddr_nl snl; +	struct iovec iov = {.iov_base = (void *)n, .iov_len = n->nlmsg_len}; +	struct msghdr msg = { +		.msg_name = (void *)&snl, +		.msg_namelen = sizeof snl, +		.msg_iov = &iov, +		.msg_iovlen = 1, +	}; +	int save_errno; + +	memset(&snl, 0, sizeof snl); +	snl.nl_family = AF_NETLINK; + +	n->nlmsg_seq = ++nl->seq; + +	/* Request an acknowledgement by setting NLM_F_ACK */ +	n->nlmsg_flags |= NLM_F_ACK; + +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug( +			"netlink_talk: %s type %s(%u), len=%d seq=%u flags 0x%x", +			nl->name, nl_msg_type_to_str(n->nlmsg_type), +			n->nlmsg_type, n->nlmsg_len, n->nlmsg_seq, +			n->nlmsg_flags); + +	/* Send message to netlink interface. */ +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	status = sendmsg(nl->sock, &msg, 0); +	save_errno = errno; +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) { +		zlog_debug("%s: >> netlink message dump [sent]", __func__); +		zlog_hexdump(&msg, sizeof(msg)); +	} + +	if (status < 0) { +		zlog_err("netlink_talk sendmsg() error: %s", +			 safe_strerror(save_errno)); +		return -1; +	} + + +	/* +	 * Get reply from netlink socket. +	 * The reply should either be an acknowlegement or an error. +	 */ +	return netlink_parse_info(filter, nl, zns, 0, startup);  }  /* Get type specified information from netlink. */ -int -netlink_request (int family, int type, struct nlsock *nl) +int netlink_request(int family, int type, struct nlsock *nl)  { -  int ret; -  struct sockaddr_nl snl; -  int save_errno; - -  struct -  { -    struct nlmsghdr nlh; -    struct rtgenmsg g; -  } req; - -  /* Check netlink socket. */ -  if (nl->sock < 0) -    { -      zlog_err("%s socket isn't active.", nl->name); -      return -1; -    } - -  memset (&snl, 0, sizeof snl); -  snl.nl_family = AF_NETLINK; - -  memset (&req, 0, sizeof req); -  req.nlh.nlmsg_len = sizeof req; -  req.nlh.nlmsg_type = type; -  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; -  req.nlh.nlmsg_pid = nl->snl.nl_pid; -  req.nlh.nlmsg_seq = ++nl->seq; -  req.g.rtgen_family = family; - -  /* linux appears to check capabilities on every message -   * have to raise caps for every message sent -   */ -  if (zserv_privs.change (ZPRIVS_RAISE)) -    { -      zlog_err("Can't raise privileges"); -      return -1; -    } - -  ret = sendto (nl->sock, (void *) &req, sizeof req, 0, -		(struct sockaddr *) &snl, sizeof snl); -  save_errno = errno; - -  if (zserv_privs.change (ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  if (ret < 0) -    { -      zlog_err("%s sendto failed: %s", nl->name, safe_strerror(save_errno)); -      return -1; -    } - -  return 0; +	int ret; +	struct sockaddr_nl snl; +	int save_errno; + +	struct { +		struct nlmsghdr nlh; +		struct rtgenmsg g; +	} req; + +	/* Check netlink socket. */ +	if (nl->sock < 0) { +		zlog_err("%s socket isn't active.", nl->name); +		return -1; +	} + +	memset(&snl, 0, sizeof snl); +	snl.nl_family = AF_NETLINK; + +	memset(&req, 0, sizeof req); +	req.nlh.nlmsg_len = sizeof req; +	req.nlh.nlmsg_type = type; +	req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; +	req.nlh.nlmsg_pid = nl->snl.nl_pid; +	req.nlh.nlmsg_seq = ++nl->seq; +	req.g.rtgen_family = family; + +	/* linux appears to check capabilities on every message +	 * have to raise caps for every message sent +	 */ +	if (zserv_privs.change(ZPRIVS_RAISE)) { +		zlog_err("Can't raise privileges"); +		return -1; +	} + +	ret = sendto(nl->sock, (void *)&req, sizeof req, 0, +		     (struct sockaddr *)&snl, sizeof snl); +	save_errno = errno; + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (ret < 0) { +		zlog_err("%s sendto failed: %s", nl->name, +			 safe_strerror(save_errno)); +		return -1; +	} + +	return 0;  }  /* Exported interface function.  This function simply calls     netlink_socket (). */ -void -kernel_init (struct zebra_ns *zns) +void kernel_init(struct zebra_ns *zns)  { -  unsigned long groups; - -  /* Initialize netlink sockets */ -  groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR | -    RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR | -    RTMGRP_IPV4_MROUTE; - -  snprintf (zns->netlink.name, sizeof (zns->netlink.name), -	    "netlink-listen (NS %u)", zns->ns_id); -  zns->netlink.sock = -1; -  netlink_socket (&zns->netlink, groups, zns->ns_id); - -  snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), -	    "netlink-cmd (NS %u)", zns->ns_id); -  zns->netlink_cmd.sock = -1; -  netlink_socket (&zns->netlink_cmd, 0, zns->ns_id); - -  /* Register kernel socket. */ -  if (zns->netlink.sock > 0) -    { -      /* Only want non-blocking on the netlink event socket */ -      if (fcntl (zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0) -        zlog_err ("Can't set %s socket flags: %s", zns->netlink.name, -                  safe_strerror (errno)); - -      /* Set receive buffer size if it's set from command line */ -      if (nl_rcvbufsize) -        netlink_recvbuf (&zns->netlink, nl_rcvbufsize); - -      netlink_install_filter (zns->netlink.sock, zns->netlink_cmd.snl.nl_pid); -      zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns, -                                         zns->netlink.sock); -    } +	unsigned long groups; + +	/* Initialize netlink sockets */ +	groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR +		 | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_MROUTE; + +	snprintf(zns->netlink.name, sizeof(zns->netlink.name), +		 "netlink-listen (NS %u)", zns->ns_id); +	zns->netlink.sock = -1; +	netlink_socket(&zns->netlink, groups, zns->ns_id); + +	snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name), +		 "netlink-cmd (NS %u)", zns->ns_id); +	zns->netlink_cmd.sock = -1; +	netlink_socket(&zns->netlink_cmd, 0, zns->ns_id); + +	/* Register kernel socket. */ +	if (zns->netlink.sock > 0) { +		/* Only want non-blocking on the netlink event socket */ +		if (fcntl(zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0) +			zlog_err("Can't set %s socket flags: %s", +				 zns->netlink.name, safe_strerror(errno)); + +		/* Set receive buffer size if it's set from command line */ +		if (nl_rcvbufsize) +			netlink_recvbuf(&zns->netlink, nl_rcvbufsize); + +		netlink_install_filter(zns->netlink.sock, +				       zns->netlink_cmd.snl.nl_pid); +		zns->t_netlink = thread_add_read(zebrad.master, kernel_read, +						 zns, zns->netlink.sock); +	}  } -void -kernel_terminate (struct zebra_ns *zns) +void kernel_terminate(struct zebra_ns *zns)  { -  THREAD_READ_OFF (zns->t_netlink); - -  if (zns->netlink.sock >= 0) -    { -      close (zns->netlink.sock); -      zns->netlink.sock = -1; -    } - -  if (zns->netlink_cmd.sock >= 0) -    { -      close (zns->netlink_cmd.sock); -      zns->netlink_cmd.sock = -1; -    } +	THREAD_READ_OFF(zns->t_netlink); + +	if (zns->netlink.sock >= 0) { +		close(zns->netlink.sock); +		zns->netlink.sock = -1; +	} + +	if (zns->netlink_cmd.sock >= 0) { +		close(zns->netlink_cmd.sock); +		zns->netlink_cmd.sock = -1; +	}  }  | 
