File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / zebra / rt_netlink.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /* Kernel routing table updates using netlink over GNU/Linux system.
    2:  * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
    3:  *
    4:  * This file is part of GNU Zebra.
    5:  *
    6:  * GNU Zebra is free software; you can redistribute it and/or modify it
    7:  * under the terms of the GNU General Public License as published by the
    8:  * Free Software Foundation; either version 2, or (at your option) any
    9:  * later version.
   10:  *
   11:  * GNU Zebra is distributed in the hope that it will be useful, but
   12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU General Public License
   17:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   18:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   19:  * 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: #include <net/if_arp.h>
   24: 
   25: /* Hack for GNU libc version 2. */
   26: #ifndef MSG_TRUNC
   27: #define MSG_TRUNC      0x20
   28: #endif /* MSG_TRUNC */
   29: 
   30: #include "linklist.h"
   31: #include "if.h"
   32: #include "log.h"
   33: #include "prefix.h"
   34: #include "connected.h"
   35: #include "table.h"
   36: #include "memory.h"
   37: #include "rib.h"
   38: #include "thread.h"
   39: #include "privs.h"
   40: #include "vrf.h"
   41: 
   42: #include "zebra/zserv.h"
   43: #include "zebra/rt.h"
   44: #include "zebra/redistribute.h"
   45: #include "zebra/interface.h"
   46: #include "zebra/debug.h"
   47: 
   48: #include "rt_netlink.h"
   49: 
   50: static const struct message nlmsg_str[] = {
   51:   {RTM_NEWROUTE, "RTM_NEWROUTE"},
   52:   {RTM_DELROUTE, "RTM_DELROUTE"},
   53:   {RTM_GETROUTE, "RTM_GETROUTE"},
   54:   {RTM_NEWLINK,  "RTM_NEWLINK"},
   55:   {RTM_DELLINK,  "RTM_DELLINK"},
   56:   {RTM_GETLINK,  "RTM_GETLINK"},
   57:   {RTM_NEWADDR,  "RTM_NEWADDR"},
   58:   {RTM_DELADDR,  "RTM_DELADDR"},
   59:   {RTM_GETADDR,  "RTM_GETADDR"},
   60:   {0, NULL}
   61: };
   62: 
   63: extern struct zebra_t zebrad;
   64: 
   65: extern struct zebra_privs_t zserv_privs;
   66: 
   67: extern u_int32_t nl_rcvbufsize;
   68: 
   69: /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
   70:    names and ifindex values. */
   71: static void
   72: set_ifindex(struct interface *ifp, ifindex_t ifi_index)
   73: {
   74:   struct interface *oifp;
   75: 
   76:   if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
   77:     {
   78:       if (ifi_index == IFINDEX_INTERNAL)
   79:         zlog_err("Netlink is setting interface %s ifindex to reserved "
   80: 		 "internal value %u", ifp->name, ifi_index);
   81:       else
   82:         {
   83: 	  if (IS_ZEBRA_DEBUG_KERNEL)
   84: 	    zlog_debug("interface index %d was renamed from %s to %s",
   85: 	    	       ifi_index, oifp->name, ifp->name);
   86: 	  if (if_is_up(oifp))
   87: 	    zlog_err("interface rename detected on up interface: index %d "
   88: 		     "was renamed from %s to %s, results are uncertain!", 
   89: 	    	     ifi_index, oifp->name, ifp->name);
   90: 	  if_delete_update(oifp);
   91:         }
   92:     }
   93:   ifp->ifindex = ifi_index;
   94: }
   95: 
   96: #ifndef SO_RCVBUFFORCE
   97: #define SO_RCVBUFFORCE  (33)
   98: #endif
   99: 
  100: static int
  101: netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
  102: {
  103:   u_int32_t oldsize;
  104:   socklen_t newlen = sizeof(newsize);
  105:   socklen_t oldlen = sizeof(oldsize);
  106:   int ret;
  107: 
  108:   ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
  109:   if (ret < 0)
  110:     {
  111:       zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
  112: 	    safe_strerror (errno));
  113:       return -1;
  114:     }
  115: 
  116:   /* Try force option (linux >= 2.6.14) and fall back to normal set */
  117:   if ( zserv_privs.change (ZPRIVS_RAISE) )
  118:     zlog_err ("routing_socket: Can't raise privileges");
  119:   ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize,
  120: 		   sizeof(nl_rcvbufsize));
  121:   if ( zserv_privs.change (ZPRIVS_LOWER) )
  122:     zlog_err ("routing_socket: Can't lower privileges");
  123:   if (ret < 0)
  124:      ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
  125: 		      sizeof(nl_rcvbufsize));
  126:   if (ret < 0)
  127:     {
  128:       zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
  129: 	    safe_strerror (errno));
  130:       return -1;
  131:     }
  132: 
  133:   ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
  134:   if (ret < 0)
  135:     {
  136:       zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
  137: 	    safe_strerror (errno));
  138:       return -1;
  139:     }
  140: 
  141:   zlog (NULL, LOG_INFO,
  142: 	"Setting netlink socket receive buffer size: %u -> %u",
  143: 	oldsize, newsize);
  144:   return 0;
  145: }
  146: 
  147: /* Make socket for Linux netlink interface. */
  148: static int
  149: netlink_socket (struct nlsock *nl, unsigned long groups, vrf_id_t vrf_id)
  150: {
  151:   int ret;
  152:   struct sockaddr_nl snl;
  153:   int sock;
  154:   int namelen;
  155:   int save_errno;
  156: 
  157:   if (zserv_privs.change (ZPRIVS_RAISE))
  158:     {
  159:       zlog (NULL, LOG_ERR, "Can't raise privileges");
  160:       return -1;
  161:     }
  162: 
  163:   sock = vrf_socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, vrf_id);
  164:   if (sock < 0)
  165:     {
  166:       zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
  167:             safe_strerror (errno));
  168:       return -1;
  169:     }
  170: 
  171:   memset (&snl, 0, sizeof snl);
  172:   snl.nl_family = AF_NETLINK;
  173:   snl.nl_groups = groups;
  174: 
  175:   /* Bind the socket to the netlink structure for anything. */
  176:   ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
  177:   save_errno = errno;
  178:   if (zserv_privs.change (ZPRIVS_LOWER))
  179:     zlog (NULL, LOG_ERR, "Can't lower privileges");
  180: 
  181:   if (ret < 0)
  182:     {
  183:       zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s",
  184:             nl->name, snl.nl_groups, safe_strerror (save_errno));
  185:       close (sock);
  186:       return -1;
  187:     }
  188: 
  189:   /* multiple netlink sockets will have different nl_pid */
  190:   namelen = sizeof snl;
  191:   ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen);
  192:   if (ret < 0 || namelen != sizeof snl)
  193:     {
  194:       zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
  195:             safe_strerror (errno));
  196:       close (sock);
  197:       return -1;
  198:     }
  199: 
  200:   nl->snl = snl;
  201:   nl->sock = sock;
  202:   return ret;
  203: }
  204: 
  205: /* Get type specified information from netlink. */
  206: static int
  207: netlink_request (int family, int type, struct nlsock *nl)
  208: {
  209:   int ret;
  210:   struct sockaddr_nl snl;
  211:   int save_errno;
  212: 
  213:   struct
  214:   {
  215:     struct nlmsghdr nlh;
  216:     struct rtgenmsg g;
  217:   } req;
  218: 
  219: 
  220:   /* Check netlink socket. */
  221:   if (nl->sock < 0)
  222:     {
  223:       zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
  224:       return -1;
  225:     }
  226: 
  227:   memset (&snl, 0, sizeof snl);
  228:   snl.nl_family = AF_NETLINK;
  229: 
  230:   memset (&req, 0, sizeof req);
  231:   req.nlh.nlmsg_len = sizeof req;
  232:   req.nlh.nlmsg_type = type;
  233:   req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
  234:   req.nlh.nlmsg_pid = nl->snl.nl_pid;
  235:   req.nlh.nlmsg_seq = ++nl->seq;
  236:   req.g.rtgen_family = family;
  237: 
  238:   /* linux appears to check capabilities on every message 
  239:    * have to raise caps for every message sent
  240:    */
  241:   if (zserv_privs.change (ZPRIVS_RAISE))
  242:     {
  243:       zlog (NULL, LOG_ERR, "Can't raise privileges");
  244:       return -1;
  245:     }
  246: 
  247:   ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
  248:                 (struct sockaddr *) &snl, sizeof snl);
  249:   save_errno = errno;
  250: 
  251:   if (zserv_privs.change (ZPRIVS_LOWER))
  252:     zlog (NULL, LOG_ERR, "Can't lower privileges");
  253: 
  254:   if (ret < 0)
  255:     {
  256:       zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name,
  257:             safe_strerror (save_errno));
  258:       return -1;
  259:     }
  260: 
  261:   return 0;
  262: }
  263: 
  264: /* Receive message from netlink interface and pass those information
  265:    to the given function. */
  266: static int
  267: netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
  268:                                    vrf_id_t),
  269:                     struct nlsock *nl, struct zebra_vrf *zvrf)
  270: {
  271:   int status;
  272:   int ret = 0;
  273:   int error;
  274: 
  275:   while (1)
  276:     {
  277:       char buf[NL_PKT_BUF_SIZE];
  278:       struct iovec iov = {
  279:         .iov_base = buf,
  280:         .iov_len = sizeof buf
  281:       };
  282:       struct sockaddr_nl snl;
  283:       struct msghdr msg = {
  284:         .msg_name = (void *) &snl,
  285:         .msg_namelen = sizeof snl,
  286:         .msg_iov = &iov,
  287:         .msg_iovlen = 1
  288:       };
  289:       struct nlmsghdr *h;
  290: 
  291:       status = recvmsg (nl->sock, &msg, 0);
  292:       if (status < 0)
  293:         {
  294:           if (errno == EINTR)
  295:             continue;
  296:           if (errno == EWOULDBLOCK || errno == EAGAIN)
  297:             break;
  298:           zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
  299: 	  	nl->name, safe_strerror(errno));
  300:           continue;
  301:         }
  302: 
  303:       if (status == 0)
  304:         {
  305:           zlog (NULL, LOG_ERR, "%s EOF", nl->name);
  306:           return -1;
  307:         }
  308: 
  309:       if (msg.msg_namelen != sizeof snl)
  310:         {
  311:           zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
  312:                 nl->name, msg.msg_namelen);
  313:           return -1;
  314:         }
  315:       
  316:       for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
  317:            h = NLMSG_NEXT (h, status))
  318:         {
  319:           /* Finish of reading. */
  320:           if (h->nlmsg_type == NLMSG_DONE)
  321:             return ret;
  322: 
  323:           /* Error handling. */
  324:           if (h->nlmsg_type == NLMSG_ERROR)
  325:             {
  326:               struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
  327: 	      int errnum = err->error;
  328: 	      int msg_type = err->msg.nlmsg_type;
  329: 
  330:               /* If the error field is zero, then this is an ACK */
  331:               if (err->error == 0)
  332:                 {
  333:                   if (IS_ZEBRA_DEBUG_KERNEL)
  334:                     {
  335:                       zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
  336:                                  __FUNCTION__, nl->name,
  337:                                  lookup (nlmsg_str, err->msg.nlmsg_type),
  338:                                  err->msg.nlmsg_type, err->msg.nlmsg_seq,
  339:                                  err->msg.nlmsg_pid);
  340:                     }
  341: 
  342:                   /* return if not a multipart message, otherwise continue */
  343:                   if (!(h->nlmsg_flags & NLM_F_MULTI))
  344:                     {
  345:                       return 0;
  346:                     }
  347:                   continue;
  348:                 }
  349: 
  350:               if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
  351:                 {
  352:                   zlog (NULL, LOG_ERR, "%s error: message truncated",
  353:                         nl->name);
  354:                   return -1;
  355:                 }
  356: 
  357:               /* Deal with errors that occur because of races in link handling */
  358: 	      if (nl == &zvrf->netlink_cmd
  359: 		  && ((msg_type == RTM_DELROUTE &&
  360: 		       (-errnum == ENODEV || -errnum == ESRCH))
  361: 		      || (msg_type == RTM_NEWROUTE && -errnum == EEXIST)))
  362: 		{
  363: 		  if (IS_ZEBRA_DEBUG_KERNEL)
  364: 		    zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
  365: 				nl->name, safe_strerror (-errnum),
  366: 				lookup (nlmsg_str, msg_type),
  367: 				msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
  368: 		  return 0;
  369: 		}
  370: 
  371: 	      zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
  372: 			nl->name, safe_strerror (-errnum),
  373: 			lookup (nlmsg_str, msg_type),
  374: 			msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
  375:               return -1;
  376:             }
  377: 
  378:           /* OK we got netlink message. */
  379:           if (IS_ZEBRA_DEBUG_KERNEL)
  380:             zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
  381:                        nl->name,
  382:                        lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
  383:                        h->nlmsg_seq, h->nlmsg_pid);
  384: 
  385:           /* skip unsolicited messages originating from command socket
  386:            * linux sets the originators port-id for {NEW|DEL}ADDR messages,
  387:            * so this has to be checked here. */
  388:           if (nl != &zvrf->netlink_cmd
  389:               && h->nlmsg_pid == zvrf->netlink_cmd.snl.nl_pid
  390:               && (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR))
  391:             {
  392:               if (IS_ZEBRA_DEBUG_KERNEL)
  393:                 zlog_debug ("netlink_parse_info: %s packet comes from %s",
  394:                             zvrf->netlink_cmd.name, nl->name);
  395:               continue;
  396:             }
  397: 
  398:           error = (*filter) (&snl, h, zvrf->vrf_id);
  399:           if (error < 0)
  400:             {
  401:               zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
  402:               ret = error;
  403:             }
  404:         }
  405: 
  406:       /* After error care. */
  407:       if (msg.msg_flags & MSG_TRUNC)
  408:         {
  409:           zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
  410:           continue;
  411:         }
  412:       if (status)
  413:         {
  414:           zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
  415:                 status);
  416:           return -1;
  417:         }
  418:     }
  419:   return ret;
  420: }
  421: 
  422: /* Utility function for parse rtattr. */
  423: static void
  424: netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
  425:                       int len)
  426: {
  427:   while (RTA_OK (rta, len))
  428:     {
  429:       if (rta->rta_type <= max)
  430:         tb[rta->rta_type] = rta;
  431:       rta = RTA_NEXT (rta, len);
  432:     }
  433: }
  434: 
  435: /* Utility function to parse hardware link-layer address and update ifp */
  436: static void
  437: netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
  438: {
  439:   int i;
  440: 
  441:   if (tb[IFLA_ADDRESS])
  442:     {
  443:       int hw_addr_len;
  444: 
  445:       hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]);
  446: 
  447:       if (hw_addr_len > INTERFACE_HWADDR_MAX)
  448:         zlog_warn ("Hardware address is too large: %d", hw_addr_len);
  449:       else
  450:         {
  451:           ifp->hw_addr_len = hw_addr_len;
  452:           memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len);
  453: 
  454:           for (i = 0; i < hw_addr_len; i++)
  455:             if (ifp->hw_addr[i] != 0)
  456:               break;
  457: 
  458:           if (i == hw_addr_len)
  459:             ifp->hw_addr_len = 0;
  460:           else
  461:             ifp->hw_addr_len = hw_addr_len;
  462:         }
  463:     }
  464: }
  465: 
  466: static enum zebra_link_type
  467: netlink_to_zebra_link_type (unsigned int hwt)
  468: {
  469:   switch (hwt)
  470:   {
  471:     case ARPHRD_ETHER: return ZEBRA_LLT_ETHER;
  472:     case ARPHRD_EETHER: return ZEBRA_LLT_EETHER;
  473:     case ARPHRD_AX25: return ZEBRA_LLT_AX25;
  474:     case ARPHRD_PRONET: return ZEBRA_LLT_PRONET;
  475:     case ARPHRD_IEEE802: return ZEBRA_LLT_IEEE802;
  476:     case ARPHRD_ARCNET: return ZEBRA_LLT_ARCNET;
  477:     case ARPHRD_APPLETLK: return ZEBRA_LLT_APPLETLK;
  478:     case ARPHRD_DLCI: return ZEBRA_LLT_DLCI;
  479:     case ARPHRD_ATM: return ZEBRA_LLT_ATM;
  480:     case ARPHRD_METRICOM: return ZEBRA_LLT_METRICOM;
  481:     case ARPHRD_IEEE1394: return ZEBRA_LLT_IEEE1394;
  482:     case ARPHRD_EUI64: return ZEBRA_LLT_EUI64;
  483:     case ARPHRD_INFINIBAND: return ZEBRA_LLT_INFINIBAND;
  484:     case ARPHRD_SLIP: return ZEBRA_LLT_SLIP;
  485:     case ARPHRD_CSLIP: return ZEBRA_LLT_CSLIP;
  486:     case ARPHRD_SLIP6: return ZEBRA_LLT_SLIP6;
  487:     case ARPHRD_CSLIP6: return ZEBRA_LLT_CSLIP6;
  488:     case ARPHRD_RSRVD: return ZEBRA_LLT_RSRVD;
  489:     case ARPHRD_ADAPT: return ZEBRA_LLT_ADAPT;
  490:     case ARPHRD_ROSE: return ZEBRA_LLT_ROSE;
  491:     case ARPHRD_X25: return ZEBRA_LLT_X25;
  492:     case ARPHRD_PPP: return ZEBRA_LLT_PPP;
  493:     case ARPHRD_CISCO: return ZEBRA_LLT_CHDLC;
  494:     case ARPHRD_LAPB: return ZEBRA_LLT_LAPB;
  495:     case ARPHRD_RAWHDLC: return ZEBRA_LLT_RAWHDLC;
  496:     case ARPHRD_TUNNEL: return ZEBRA_LLT_IPIP;
  497:     case ARPHRD_TUNNEL6: return ZEBRA_LLT_IPIP6;
  498:     case ARPHRD_FRAD: return ZEBRA_LLT_FRAD;
  499:     case ARPHRD_SKIP: return ZEBRA_LLT_SKIP;
  500:     case ARPHRD_LOOPBACK: return ZEBRA_LLT_LOOPBACK;
  501:     case ARPHRD_LOCALTLK: return ZEBRA_LLT_LOCALTLK;
  502:     case ARPHRD_FDDI: return ZEBRA_LLT_FDDI;
  503:     case ARPHRD_SIT: return ZEBRA_LLT_SIT;
  504:     case ARPHRD_IPDDP: return ZEBRA_LLT_IPDDP;
  505:     case ARPHRD_IPGRE: return ZEBRA_LLT_IPGRE;
  506:     case ARPHRD_PIMREG: return ZEBRA_LLT_PIMREG;
  507:     case ARPHRD_HIPPI: return ZEBRA_LLT_HIPPI;
  508:     case ARPHRD_ECONET: return ZEBRA_LLT_ECONET;
  509:     case ARPHRD_IRDA: return ZEBRA_LLT_IRDA;
  510:     case ARPHRD_FCPP: return ZEBRA_LLT_FCPP;
  511:     case ARPHRD_FCAL: return ZEBRA_LLT_FCAL;
  512:     case ARPHRD_FCPL: return ZEBRA_LLT_FCPL;
  513:     case ARPHRD_FCFABRIC: return ZEBRA_LLT_FCFABRIC;
  514:     case ARPHRD_IEEE802_TR: return ZEBRA_LLT_IEEE802_TR;
  515:     case ARPHRD_IEEE80211: return ZEBRA_LLT_IEEE80211;
  516:     case ARPHRD_IEEE802154: return ZEBRA_LLT_IEEE802154;
  517: #ifdef ARPHRD_IP6GRE
  518:     case ARPHRD_IP6GRE: return ZEBRA_LLT_IP6GRE;
  519: #endif
  520: #ifdef ARPHRD_IEEE802154_PHY
  521:     case ARPHRD_IEEE802154_PHY: return ZEBRA_LLT_IEEE802154_PHY;
  522: #endif
  523: 
  524:     default: return ZEBRA_LLT_UNKNOWN;
  525:   }
  526: }
  527: 
  528: /* Called from interface_lookup_netlink().  This function is only used
  529:    during bootstrap. */
  530: static int
  531: netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
  532:     vrf_id_t vrf_id)
  533: {
  534:   int len;
  535:   struct ifinfomsg *ifi;
  536:   struct rtattr *tb[IFLA_MAX + 1];
  537:   struct interface *ifp;
  538:   char *name;
  539: 
  540:   ifi = NLMSG_DATA (h);
  541: 
  542:   if (h->nlmsg_type != RTM_NEWLINK)
  543:     return 0;
  544: 
  545:   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
  546:   if (len < 0)
  547:     return -1;
  548: 
  549:   /* Looking up interface name. */
  550:   memset (tb, 0, sizeof tb);
  551:   netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
  552:   
  553: #ifdef IFLA_WIRELESS
  554:   /* check for wireless messages to ignore */
  555:   if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
  556:     {
  557:       if (IS_ZEBRA_DEBUG_KERNEL)
  558:         zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
  559:       return 0;
  560:     }
  561: #endif /* IFLA_WIRELESS */
  562: 
  563:   if (tb[IFLA_IFNAME] == NULL)
  564:     return -1;
  565:   name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
  566: 
  567:   /* Add interface. */
  568:   ifp = if_get_by_name_vrf (name, vrf_id);
  569:   set_ifindex(ifp, ifi->ifi_index);
  570:   ifp->flags = ifi->ifi_flags & 0x0000fffff;
  571:   ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
  572:   ifp->metric = 0;
  573: 
  574:   /* Hardware type and address. */
  575:   ifp->ll_type = netlink_to_zebra_link_type (ifi->ifi_type);
  576:   netlink_interface_update_hw_addr (tb, ifp);
  577: 
  578:   if_add_update (ifp);
  579: 
  580:   return 0;
  581: }
  582: 
  583: /* Lookup interface IPv4/IPv6 address. */
  584: static int
  585: netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
  586:     vrf_id_t vrf_id)
  587: {
  588:   int len;
  589:   struct ifaddrmsg *ifa;
  590:   struct rtattr *tb[IFA_MAX + 1];
  591:   struct interface *ifp;
  592:   void *addr;
  593:   void *broad;
  594:   u_char flags = 0;
  595:   char *label = NULL;
  596: 
  597:   ifa = NLMSG_DATA (h);
  598: 
  599:   if (ifa->ifa_family != AF_INET
  600: #ifdef HAVE_IPV6
  601:       && ifa->ifa_family != AF_INET6
  602: #endif /* HAVE_IPV6 */
  603:     )
  604:     return 0;
  605: 
  606:   if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
  607:     return 0;
  608: 
  609:   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg));
  610:   if (len < 0)
  611:     return -1;
  612: 
  613:   memset (tb, 0, sizeof tb);
  614:   netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
  615: 
  616:   ifp = if_lookup_by_index_vrf (ifa->ifa_index, vrf_id);
  617:   if (ifp == NULL)
  618:     {
  619:       zlog_err ("netlink_interface_addr can't find interface by index %d vrf %u",
  620:                 ifa->ifa_index, vrf_id);
  621:       return -1;
  622:     }
  623: 
  624:   if (IS_ZEBRA_DEBUG_KERNEL)    /* remove this line to see initial ifcfg */
  625:     {
  626:       char buf[BUFSIZ];
  627:       zlog_debug ("netlink_interface_addr %s %s vrf %u:",
  628:                  lookup (nlmsg_str, h->nlmsg_type), ifp->name, vrf_id);
  629:       if (tb[IFA_LOCAL])
  630:         zlog_debug ("  IFA_LOCAL     %s/%d",
  631: 		    inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
  632: 			       buf, BUFSIZ), ifa->ifa_prefixlen);
  633:       if (tb[IFA_ADDRESS])
  634:         zlog_debug ("  IFA_ADDRESS   %s/%d",
  635: 		    inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]),
  636:                                buf, BUFSIZ), ifa->ifa_prefixlen);
  637:       if (tb[IFA_BROADCAST])
  638:         zlog_debug ("  IFA_BROADCAST %s/%d",
  639: 		    inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]),
  640: 			       buf, BUFSIZ), ifa->ifa_prefixlen);
  641:       if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
  642:         zlog_debug ("  IFA_LABEL     %s", (char *)RTA_DATA (tb[IFA_LABEL]));
  643:       
  644:       if (tb[IFA_CACHEINFO])
  645:         {
  646:           struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]);
  647:           zlog_debug ("  IFA_CACHEINFO pref %d, valid %d",
  648:                       ci->ifa_prefered, ci->ifa_valid);
  649:         }
  650:     }
  651:   
  652:   /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
  653:   if (tb[IFA_LOCAL] == NULL)
  654:     tb[IFA_LOCAL] = tb[IFA_ADDRESS];
  655:   if (tb[IFA_ADDRESS] == NULL)
  656:     tb[IFA_ADDRESS] = tb[IFA_LOCAL];
  657:   
  658:   /* local interface address */
  659:   addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
  660: 
  661:   /* is there a peer address? */
  662:   if (tb[IFA_ADDRESS] &&
  663:       memcmp(RTA_DATA(tb[IFA_ADDRESS]), RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_ADDRESS])))
  664:     {
  665:       broad = RTA_DATA(tb[IFA_ADDRESS]);
  666:       SET_FLAG (flags, ZEBRA_IFA_PEER);
  667:     }
  668:   else
  669:     /* seeking a broadcast address */
  670:     broad = (tb[IFA_BROADCAST] ? RTA_DATA(tb[IFA_BROADCAST]) : NULL);
  671: 
  672:   /* addr is primary key, SOL if we don't have one */
  673:   if (addr == NULL)
  674:     {
  675:       zlog_debug ("%s: NULL address", __func__);
  676:       return -1;
  677:     }
  678: 
  679:   /* Flags. */
  680:   if (ifa->ifa_flags & IFA_F_SECONDARY)
  681:     SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
  682: 
  683:   /* Label */
  684:   if (tb[IFA_LABEL])
  685:     label = (char *) RTA_DATA (tb[IFA_LABEL]);
  686: 
  687:   if (ifp && label && strcmp (ifp->name, label) == 0)
  688:     label = NULL;
  689: 
  690:   /* Register interface address to the interface. */
  691:   if (ifa->ifa_family == AF_INET)
  692:     {
  693:       if (h->nlmsg_type == RTM_NEWADDR)
  694:         connected_add_ipv4 (ifp, flags,
  695:                             (struct in_addr *) addr, ifa->ifa_prefixlen,
  696:                             (struct in_addr *) broad, label);
  697:       else
  698:         connected_delete_ipv4 (ifp, flags,
  699:                                (struct in_addr *) addr, ifa->ifa_prefixlen,
  700:                                (struct in_addr *) broad);
  701:     }
  702: #ifdef HAVE_IPV6
  703:   if (ifa->ifa_family == AF_INET6)
  704:     {
  705:       if (h->nlmsg_type == RTM_NEWADDR)
  706:         connected_add_ipv6 (ifp, flags,
  707:                             (struct in6_addr *) addr, ifa->ifa_prefixlen,
  708:                             (struct in6_addr *) broad, label);
  709:       else
  710:         connected_delete_ipv6 (ifp,
  711:                                (struct in6_addr *) addr, ifa->ifa_prefixlen,
  712:                                (struct in6_addr *) broad);
  713:     }
  714: #endif /* HAVE_IPV6 */
  715: 
  716:   return 0;
  717: }
  718: 
  719: /* Looking up routing table by netlink interface. */
  720: static int
  721: netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
  722:     vrf_id_t vrf_id)
  723: {
  724:   int len;
  725:   struct rtmsg *rtm;
  726:   struct rtattr *tb[RTA_MAX + 1];
  727:   u_char flags = 0;
  728: 
  729:   char anyaddr[16] = { 0 };
  730: 
  731:   int index;
  732:   int table;
  733:   u_int32_t mtu = 0;
  734: 
  735:   void *dest;
  736:   void *gate;
  737:   void *src;
  738: 
  739:   rtm = NLMSG_DATA (h);
  740: 
  741:   if (h->nlmsg_type != RTM_NEWROUTE)
  742:     return 0;
  743:   if (rtm->rtm_type != RTN_UNICAST)
  744:     return 0;
  745: 
  746:   table = rtm->rtm_table;
  747: #if 0                           /* we weed them out later in rib_weed_tables () */
  748:   if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
  749:     return 0;
  750: #endif
  751: 
  752:   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
  753:   if (len < 0)
  754:     return -1;
  755: 
  756:   memset (tb, 0, sizeof tb);
  757:   netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
  758: 
  759:   if (rtm->rtm_flags & RTM_F_CLONED)
  760:     return 0;
  761:   if (rtm->rtm_protocol == RTPROT_REDIRECT)
  762:     return 0;
  763:   if (rtm->rtm_protocol == RTPROT_KERNEL)
  764:     return 0;
  765: 
  766:   if (rtm->rtm_src_len != 0)
  767:     return 0;
  768: 
  769:   /* Route which inserted by Zebra. */
  770:   if (rtm->rtm_protocol == RTPROT_ZEBRA)
  771:     flags |= ZEBRA_FLAG_SELFROUTE;
  772: 
  773:   index = 0;
  774:   dest = NULL;
  775:   gate = NULL;
  776:   src = NULL;
  777: 
  778:   if (tb[RTA_OIF])
  779:     index = *(int *) RTA_DATA (tb[RTA_OIF]);
  780: 
  781:   if (tb[RTA_DST])
  782:     dest = RTA_DATA (tb[RTA_DST]);
  783:   else
  784:     dest = anyaddr;
  785: 
  786:   if (tb[RTA_PREFSRC])
  787:     src = RTA_DATA (tb[RTA_PREFSRC]);
  788: 
  789:   if (tb[RTA_GATEWAY])
  790:     gate = RTA_DATA (tb[RTA_GATEWAY]);
  791: 
  792:   if (tb[RTA_METRICS])
  793:     {
  794:       struct rtattr *mxrta[RTAX_MAX+1];
  795: 
  796:       memset (mxrta, 0, sizeof mxrta);
  797:       netlink_parse_rtattr (mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]),
  798:                             RTA_PAYLOAD(tb[RTA_METRICS]));
  799: 
  800:       if (mxrta[RTAX_MTU])
  801:         mtu = *(u_int32_t *) RTA_DATA(mxrta[RTAX_MTU]);
  802:     }
  803: 
  804:   if (rtm->rtm_family == AF_INET)
  805:     {
  806:       struct prefix_ipv4 p;
  807:       p.family = AF_INET;
  808:       memcpy (&p.prefix, dest, 4);
  809:       p.prefixlen = rtm->rtm_dst_len;
  810: 
  811:       if (!tb[RTA_MULTIPATH])
  812:           rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index,
  813:                         vrf_id, table, 0, mtu, 0, SAFI_UNICAST);
  814:       else
  815:         {
  816:           /* This is a multipath route */
  817: 
  818:           struct rib *rib;
  819:           struct rtnexthop *rtnh =
  820:             (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
  821: 
  822:           len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
  823: 
  824:           rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
  825:           rib->type = ZEBRA_ROUTE_KERNEL;
  826:           rib->distance = 0;
  827:           rib->flags = flags;
  828:           rib->metric = 0;
  829:           rib->mtu = mtu;
  830:           rib->vrf_id = vrf_id;
  831:           rib->table = table;
  832:           rib->nexthop_num = 0;
  833:           rib->uptime = time (NULL);
  834: 
  835:           for (;;)
  836:             {
  837:               if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
  838:                 break;
  839: 
  840:               index = rtnh->rtnh_ifindex;
  841:               gate = 0;
  842:               if (rtnh->rtnh_len > sizeof (*rtnh))
  843:                 {
  844:                   memset (tb, 0, sizeof (tb));
  845:                   netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
  846:                                         rtnh->rtnh_len - sizeof (*rtnh));
  847:                   if (tb[RTA_GATEWAY])
  848:                     gate = RTA_DATA (tb[RTA_GATEWAY]);
  849:                 }
  850: 
  851:               if (gate)
  852:                 {
  853:                   if (index)
  854:                     nexthop_ipv4_ifindex_add (rib, gate, src, index);
  855:                   else
  856:                     nexthop_ipv4_add (rib, gate, src);
  857:                 }
  858:               else
  859:                 nexthop_ifindex_add (rib, index);
  860: 
  861:               len -= NLMSG_ALIGN(rtnh->rtnh_len);
  862:               rtnh = RTNH_NEXT(rtnh);
  863:             }
  864: 
  865:           if (rib->nexthop_num == 0)
  866:             XFREE (MTYPE_RIB, rib);
  867:           else
  868:             rib_add_ipv4_multipath (&p, rib, SAFI_UNICAST);
  869:         }
  870:     }
  871: #ifdef HAVE_IPV6
  872:   if (rtm->rtm_family == AF_INET6)
  873:     {
  874:       struct prefix_ipv6 p;
  875:       p.family = AF_INET6;
  876:       memcpy (&p.prefix, dest, 16);
  877:       p.prefixlen = rtm->rtm_dst_len;
  878: 
  879:       rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, vrf_id,
  880:                     table, 0, mtu, 0, SAFI_UNICAST);
  881:     }
  882: #endif /* HAVE_IPV6 */
  883: 
  884:   return 0;
  885: }
  886: 
  887: static const struct message rtproto_str[] = {
  888:   {RTPROT_REDIRECT, "redirect"},
  889:   {RTPROT_KERNEL,   "kernel"},
  890:   {RTPROT_BOOT,     "boot"},
  891:   {RTPROT_STATIC,   "static"},
  892:   {RTPROT_GATED,    "GateD"},
  893:   {RTPROT_RA,       "router advertisement"},
  894:   {RTPROT_MRT,      "MRT"},
  895:   {RTPROT_ZEBRA,    "Zebra"},
  896: #ifdef RTPROT_BIRD
  897:   {RTPROT_BIRD,     "BIRD"},
  898: #endif /* RTPROT_BIRD */
  899:   {0,               NULL}
  900: };
  901: 
  902: /* Routing information change from the kernel. */
  903: static int
  904: netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
  905:     vrf_id_t vrf_id)
  906: {
  907:   int len;
  908:   struct rtmsg *rtm;
  909:   struct rtattr *tb[RTA_MAX + 1];
  910: 
  911:   char anyaddr[16] = { 0 };
  912: 
  913:   int index;
  914:   int table;
  915:   u_int32_t mtu = 0;
  916: 
  917:   void *dest;
  918:   void *gate;
  919:   void *src;
  920: 
  921:   rtm = NLMSG_DATA (h);
  922: 
  923:   if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
  924:     {
  925:       /* If this is not route add/delete message print warning. */
  926:       zlog_warn ("Kernel message: %d vrf %u\n", h->nlmsg_type, vrf_id);
  927:       return 0;
  928:     }
  929: 
  930:   /* Connected route. */
  931:   if (IS_ZEBRA_DEBUG_KERNEL)
  932:     zlog_debug ("%s %s %s proto %s vrf %u",
  933:                h->nlmsg_type ==
  934:                RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
  935:                rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
  936:                rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
  937:                lookup (rtproto_str, rtm->rtm_protocol),
  938:                vrf_id);
  939: 
  940:   if (rtm->rtm_type != RTN_UNICAST)
  941:     {
  942:       return 0;
  943:     }
  944: 
  945:   table = rtm->rtm_table;
  946:   if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
  947:     {
  948:       return 0;
  949:     }
  950: 
  951:   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
  952:   if (len < 0)
  953:     return -1;
  954: 
  955:   memset (tb, 0, sizeof tb);
  956:   netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
  957: 
  958:   if (rtm->rtm_flags & RTM_F_CLONED)
  959:     return 0;
  960:   if (rtm->rtm_protocol == RTPROT_REDIRECT)
  961:     return 0;
  962:   if (rtm->rtm_protocol == RTPROT_KERNEL)
  963:     return 0;
  964: 
  965:   if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
  966:     return 0;
  967: 
  968:   if (rtm->rtm_src_len != 0)
  969:     {
  970:       zlog_warn ("netlink_route_change(): no src len, vrf %u", vrf_id);
  971:       return 0;
  972:     }
  973: 
  974:   index = 0;
  975:   dest = NULL;
  976:   gate = NULL;
  977:   src = NULL;
  978: 
  979:   if (tb[RTA_OIF])
  980:     index = *(int *) RTA_DATA (tb[RTA_OIF]);
  981: 
  982:   if (tb[RTA_DST])
  983:     dest = RTA_DATA (tb[RTA_DST]);
  984:   else
  985:     dest = anyaddr;
  986: 
  987:   if (tb[RTA_GATEWAY])
  988:     gate = RTA_DATA (tb[RTA_GATEWAY]);
  989: 
  990:   if (tb[RTA_PREFSRC])
  991:     src = RTA_DATA (tb[RTA_PREFSRC]);
  992: 
  993:   if (h->nlmsg_type == RTM_NEWROUTE)
  994:     {
  995:       if (tb[RTA_METRICS])
  996:         {
  997:           struct rtattr *mxrta[RTAX_MAX+1];
  998: 
  999:           memset (mxrta, 0, sizeof mxrta);
 1000:           netlink_parse_rtattr (mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]),
 1001:                                 RTA_PAYLOAD(tb[RTA_METRICS]));
 1002: 
 1003:           if (mxrta[RTAX_MTU])
 1004:             mtu = *(u_int32_t *) RTA_DATA(mxrta[RTAX_MTU]);
 1005:         }
 1006:     }
 1007: 
 1008:   if (rtm->rtm_family == AF_INET)
 1009:     {
 1010:       struct prefix_ipv4 p;
 1011:       p.family = AF_INET;
 1012:       memcpy (&p.prefix, dest, 4);
 1013:       p.prefixlen = rtm->rtm_dst_len;
 1014: 
 1015:       if (IS_ZEBRA_DEBUG_KERNEL)
 1016:         {
 1017:           char buf[PREFIX_STRLEN];
 1018:           zlog_debug ("%s %s vrf %u",
 1019:                       h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
 1020:                       prefix2str (&p, buf, sizeof(buf)), vrf_id);
 1021:         }
 1022: 
 1023:       if (h->nlmsg_type == RTM_NEWROUTE)
 1024:         {
 1025:           if (!tb[RTA_MULTIPATH])
 1026:             rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, vrf_id,
 1027:                           table, 0, mtu, 0, SAFI_UNICAST);
 1028:           else
 1029:             {
 1030:               /* This is a multipath route */
 1031: 
 1032:               struct rib *rib;
 1033:               struct rtnexthop *rtnh =
 1034:                 (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
 1035: 
 1036:               len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
 1037: 
 1038:               rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
 1039:               rib->type = ZEBRA_ROUTE_KERNEL;
 1040:               rib->distance = 0;
 1041:               rib->flags = 0;
 1042:               rib->metric = 0;
 1043:               rib->mtu = mtu;
 1044:               rib->vrf_id = vrf_id;
 1045:               rib->table = table;
 1046:               rib->nexthop_num = 0;
 1047:               rib->uptime = time (NULL);
 1048: 
 1049:               for (;;)
 1050:                 {
 1051:                   if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
 1052:                     break;
 1053: 
 1054:                   index = rtnh->rtnh_ifindex;
 1055:                   gate = 0;
 1056:                   if (rtnh->rtnh_len > sizeof (*rtnh))
 1057:                     {
 1058:                       memset (tb, 0, sizeof (tb));
 1059:                       netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
 1060:                                             rtnh->rtnh_len - sizeof (*rtnh));
 1061:                       if (tb[RTA_GATEWAY])
 1062:                         gate = RTA_DATA (tb[RTA_GATEWAY]);
 1063:                     }
 1064: 
 1065:                   if (gate)
 1066:                     {
 1067:                       if (index)
 1068:                         nexthop_ipv4_ifindex_add (rib, gate, src, index);
 1069:                       else
 1070:                         nexthop_ipv4_add (rib, gate, src);
 1071:                     }
 1072:                   else
 1073:                     nexthop_ifindex_add (rib, index);
 1074: 
 1075:                   len -= NLMSG_ALIGN(rtnh->rtnh_len);
 1076:                   rtnh = RTNH_NEXT(rtnh);
 1077:                 }
 1078: 
 1079:               if (rib->nexthop_num == 0)
 1080:                 XFREE (MTYPE_RIB, rib);
 1081:               else
 1082:                 rib_add_ipv4_multipath (&p, rib, SAFI_UNICAST);
 1083:             }
 1084:         }
 1085:       else
 1086:         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id,
 1087:                          SAFI_UNICAST);
 1088:     }
 1089: 
 1090: #ifdef HAVE_IPV6
 1091:   if (rtm->rtm_family == AF_INET6)
 1092:     {
 1093:       struct prefix_ipv6 p;
 1094: 
 1095:       p.family = AF_INET6;
 1096:       memcpy (&p.prefix, dest, 16);
 1097:       p.prefixlen = rtm->rtm_dst_len;
 1098: 
 1099:       if (IS_ZEBRA_DEBUG_KERNEL)
 1100:         {
 1101:           char buf[PREFIX_STRLEN];
 1102:           zlog_debug ("%s %s vrf %u",
 1103:                       h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
 1104:                       prefix2str (&p, buf, sizeof(buf)), vrf_id);
 1105:         }
 1106: 
 1107:       if (h->nlmsg_type == RTM_NEWROUTE)
 1108:         rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, table,
 1109:                       0, mtu, 0, SAFI_UNICAST);
 1110:       else
 1111:         rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id,
 1112:                          SAFI_UNICAST);
 1113:     }
 1114: #endif /* HAVE_IPV6 */
 1115: 
 1116:   return 0;
 1117: }
 1118: 
 1119: static int
 1120: netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
 1121:     vrf_id_t vrf_id)
 1122: {
 1123:   int len;
 1124:   struct ifinfomsg *ifi;
 1125:   struct rtattr *tb[IFLA_MAX + 1];
 1126:   struct interface *ifp;
 1127:   char *name;
 1128: 
 1129:   ifi = NLMSG_DATA (h);
 1130: 
 1131:   if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
 1132:     {
 1133:       /* If this is not link add/delete message so print warning. */
 1134:       zlog_warn ("netlink_link_change: wrong kernel message %d vrf %u\n",
 1135:                  h->nlmsg_type, vrf_id);
 1136:       return 0;
 1137:     }
 1138: 
 1139:   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
 1140:   if (len < 0)
 1141:     return -1;
 1142: 
 1143:   /* Looking up interface name. */
 1144:   memset (tb, 0, sizeof tb);
 1145:   netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
 1146: 
 1147: #ifdef IFLA_WIRELESS
 1148:   /* check for wireless messages to ignore */
 1149:   if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
 1150:     {
 1151:       if (IS_ZEBRA_DEBUG_KERNEL)
 1152:         zlog_debug ("%s: ignoring IFLA_WIRELESS message, vrf %u", __func__,
 1153:                     vrf_id);
 1154:       return 0;
 1155:     }
 1156: #endif /* IFLA_WIRELESS */
 1157:   
 1158:   if (tb[IFLA_IFNAME] == NULL)
 1159:     return -1;
 1160:   name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
 1161: 
 1162:   /* Add interface. */
 1163:   if (h->nlmsg_type == RTM_NEWLINK)
 1164:     {
 1165:       ifp = if_lookup_by_name_vrf (name, vrf_id);
 1166: 
 1167:       if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
 1168:         {
 1169:           if (ifp == NULL)
 1170:             ifp = if_get_by_name_vrf (name, vrf_id);
 1171: 
 1172:           set_ifindex(ifp, ifi->ifi_index);
 1173:           ifp->flags = ifi->ifi_flags & 0x0000fffff;
 1174:           ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
 1175:           ifp->metric = 0;
 1176: 
 1177:           netlink_interface_update_hw_addr (tb, ifp);
 1178: 
 1179:           /* If new link is added. */
 1180:           if_add_update (ifp);
 1181:         }
 1182:       else
 1183:         {
 1184:           /* Interface status change. */
 1185:           set_ifindex(ifp, ifi->ifi_index);
 1186:           ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
 1187:           ifp->metric = 0;
 1188: 
 1189:           netlink_interface_update_hw_addr (tb, ifp);
 1190: 
 1191:           if (if_is_operative (ifp))
 1192:             {
 1193:               ifp->flags = ifi->ifi_flags & 0x0000fffff;
 1194:               if (!if_is_operative (ifp))
 1195:                 if_down (ifp);
 1196: 	      else
 1197: 		/* Must notify client daemons of new interface status. */
 1198: 	        zebra_interface_up_update (ifp);
 1199:             }
 1200:           else
 1201:             {
 1202:               ifp->flags = ifi->ifi_flags & 0x0000fffff;
 1203:               if (if_is_operative (ifp))
 1204:                 if_up (ifp);
 1205:             }
 1206:         }
 1207:     }
 1208:   else
 1209:     {
 1210:       /* RTM_DELLINK. */
 1211:       ifp = if_lookup_by_name_vrf (name, vrf_id);
 1212: 
 1213:       if (ifp == NULL)
 1214:         {
 1215:           zlog_warn ("interface %s vrf %u is deleted but can't find",
 1216:                      name, vrf_id);
 1217:           return 0;
 1218:         }
 1219: 
 1220:       if_delete_update (ifp);
 1221:     }
 1222: 
 1223:   return 0;
 1224: }
 1225: 
 1226: static int
 1227: netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h,
 1228:     vrf_id_t vrf_id)
 1229: {
 1230:   /* JF: Ignore messages that aren't from the kernel */
 1231:   if ( snl->nl_pid != 0 )
 1232:     {
 1233:       zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl->nl_pid );
 1234:       return 0;
 1235:     }
 1236: 
 1237:   switch (h->nlmsg_type)
 1238:     {
 1239:     case RTM_NEWROUTE:
 1240:       return netlink_route_change (snl, h, vrf_id);
 1241:       break;
 1242:     case RTM_DELROUTE:
 1243:       return netlink_route_change (snl, h, vrf_id);
 1244:       break;
 1245:     case RTM_NEWLINK:
 1246:       return netlink_link_change (snl, h, vrf_id);
 1247:       break;
 1248:     case RTM_DELLINK:
 1249:       return netlink_link_change (snl, h, vrf_id);
 1250:       break;
 1251:     case RTM_NEWADDR:
 1252:       return netlink_interface_addr (snl, h, vrf_id);
 1253:       break;
 1254:     case RTM_DELADDR:
 1255:       return netlink_interface_addr (snl, h, vrf_id);
 1256:       break;
 1257:     default:
 1258:       zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type,
 1259:                  vrf_id);
 1260:       break;
 1261:     }
 1262:   return 0;
 1263: }
 1264: 
 1265: /* Interface lookup by netlink socket. */
 1266: int
 1267: interface_lookup_netlink (struct zebra_vrf *zvrf)
 1268: {
 1269:   int ret;
 1270: 
 1271:   /* Get interface information. */
 1272:   ret = netlink_request (AF_PACKET, RTM_GETLINK, &zvrf->netlink_cmd);
 1273:   if (ret < 0)
 1274:     return ret;
 1275:   ret = netlink_parse_info (netlink_interface, &zvrf->netlink_cmd, zvrf);
 1276:   if (ret < 0)
 1277:     return ret;
 1278: 
 1279:   /* Get IPv4 address of the interfaces. */
 1280:   ret = netlink_request (AF_INET, RTM_GETADDR, &zvrf->netlink_cmd);
 1281:   if (ret < 0)
 1282:     return ret;
 1283:   ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
 1284:   if (ret < 0)
 1285:     return ret;
 1286: 
 1287: #ifdef HAVE_IPV6
 1288:   /* Get IPv6 address of the interfaces. */
 1289:   ret = netlink_request (AF_INET6, RTM_GETADDR, &zvrf->netlink_cmd);
 1290:   if (ret < 0)
 1291:     return ret;
 1292:   ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
 1293:   if (ret < 0)
 1294:     return ret;
 1295: #endif /* HAVE_IPV6 */
 1296: 
 1297:   return 0;
 1298: }
 1299: 
 1300: /* Routing table read function using netlink interface.  Only called
 1301:    bootstrap time. */
 1302: int
 1303: netlink_route_read (struct zebra_vrf *zvrf)
 1304: {
 1305:   int ret;
 1306: 
 1307:   /* Get IPv4 routing table. */
 1308:   ret = netlink_request (AF_INET, RTM_GETROUTE, &zvrf->netlink_cmd);
 1309:   if (ret < 0)
 1310:     return ret;
 1311:   ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
 1312:   if (ret < 0)
 1313:     return ret;
 1314: 
 1315: #ifdef HAVE_IPV6
 1316:   /* Get IPv6 routing table. */
 1317:   ret = netlink_request (AF_INET6, RTM_GETROUTE, &zvrf->netlink_cmd);
 1318:   if (ret < 0)
 1319:     return ret;
 1320:   ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
 1321:   if (ret < 0)
 1322:     return ret;
 1323: #endif /* HAVE_IPV6 */
 1324: 
 1325:   return 0;
 1326: }
 1327: 
 1328: /* Utility function  comes from iproute2. 
 1329:    Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
 1330: int
 1331: addattr_l (struct nlmsghdr *n, size_t maxlen, int type, void *data, int alen)
 1332: {
 1333:   size_t len;
 1334:   struct rtattr *rta;
 1335: 
 1336:   len = RTA_LENGTH (alen);
 1337: 
 1338:   if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
 1339:     return -1;
 1340: 
 1341:   rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
 1342:   rta->rta_type = type;
 1343:   rta->rta_len = len;
 1344:   memcpy (RTA_DATA (rta), data, alen);
 1345:   n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
 1346: 
 1347:   return 0;
 1348: }
 1349: 
 1350: int
 1351: rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
 1352: {
 1353:   int len;
 1354:   struct rtattr *subrta;
 1355: 
 1356:   len = RTA_LENGTH (alen);
 1357: 
 1358:   if (RTA_ALIGN (rta->rta_len) + len > maxlen)
 1359:     return -1;
 1360: 
 1361:   subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
 1362:   subrta->rta_type = type;
 1363:   subrta->rta_len = len;
 1364:   memcpy (RTA_DATA (subrta), data, alen);
 1365:   rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
 1366: 
 1367:   return 0;
 1368: }
 1369: 
 1370: /* Utility function comes from iproute2. 
 1371:    Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
 1372: int
 1373: addattr32 (struct nlmsghdr *n, size_t maxlen, int type, int data)
 1374: {
 1375:   size_t len;
 1376:   struct rtattr *rta;
 1377: 
 1378:   len = RTA_LENGTH (4);
 1379: 
 1380:   if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
 1381:     return -1;
 1382: 
 1383:   rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
 1384:   rta->rta_type = type;
 1385:   rta->rta_len = len;
 1386:   memcpy (RTA_DATA (rta), &data, 4);
 1387:   n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
 1388: 
 1389:   return 0;
 1390: }
 1391: 
 1392: static int
 1393: netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h,
 1394:     vrf_id_t vrf_id)
 1395: {
 1396:   zlog_warn ("netlink_talk: ignoring message type 0x%04x vrf %u", h->nlmsg_type,
 1397:              vrf_id);
 1398:   return 0;
 1399: }
 1400: 
 1401: /* sendmsg() to netlink socket then recvmsg(). */
 1402: static int
 1403: netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_vrf *zvrf)
 1404: {
 1405:   int status;
 1406:   struct sockaddr_nl snl;
 1407:   struct iovec iov = {
 1408:     .iov_base = (void *) n,
 1409:     .iov_len = n->nlmsg_len
 1410:   };
 1411:   struct msghdr msg = {
 1412:     .msg_name = (void *) &snl,
 1413:     .msg_namelen = sizeof snl,
 1414:     .msg_iov = &iov,
 1415:     .msg_iovlen = 1,
 1416:   };
 1417:   int save_errno;
 1418: 
 1419:   memset (&snl, 0, sizeof snl);
 1420:   snl.nl_family = AF_NETLINK;
 1421: 
 1422:   n->nlmsg_seq = ++nl->seq;
 1423: 
 1424:   /* Request an acknowledgement by setting NLM_F_ACK */
 1425:   n->nlmsg_flags |= NLM_F_ACK;
 1426: 
 1427:   if (IS_ZEBRA_DEBUG_KERNEL)
 1428:     zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
 1429:                lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
 1430:                n->nlmsg_seq);
 1431: 
 1432:   /* Send message to netlink interface. */
 1433:   if (zserv_privs.change (ZPRIVS_RAISE))
 1434:     zlog (NULL, LOG_ERR, "Can't raise privileges");
 1435:   status = sendmsg (nl->sock, &msg, 0);
 1436:   save_errno = errno;
 1437:   if (zserv_privs.change (ZPRIVS_LOWER))
 1438:     zlog (NULL, LOG_ERR, "Can't lower privileges");
 1439: 
 1440:   if (status < 0)
 1441:     {
 1442:       zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
 1443:             safe_strerror (save_errno));
 1444:       return -1;
 1445:     }
 1446: 
 1447: 
 1448:   /* 
 1449:    * Get reply from netlink socket. 
 1450:    * The reply should either be an acknowlegement or an error.
 1451:    */
 1452:   return netlink_parse_info (netlink_talk_filter, nl, zvrf);
 1453: }
 1454: 
 1455: /* This function takes a nexthop as argument and adds
 1456:  * the appropriate netlink attributes to an existing
 1457:  * netlink message.
 1458:  *
 1459:  * @param routedesc: Human readable description of route type
 1460:  *                   (direct/recursive, single-/multipath)
 1461:  * @param bytelen: Length of addresses in bytes.
 1462:  * @param nexthop: Nexthop information
 1463:  * @param nlmsg: nlmsghdr structure to fill in.
 1464:  * @param req_size: The size allocated for the message.
 1465:  */
 1466: static void
 1467: _netlink_route_build_singlepath(
 1468:         const char *routedesc,
 1469:         int bytelen,
 1470:         struct nexthop *nexthop,
 1471:         struct nlmsghdr *nlmsg,
 1472:         struct rtmsg *rtmsg,
 1473:         size_t req_size)
 1474: {
 1475:   if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
 1476:     rtmsg->rtm_flags |= RTNH_F_ONLINK;
 1477:   if (nexthop->type == NEXTHOP_TYPE_IPV4
 1478:       || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
 1479:     {
 1480:       addattr_l (nlmsg, req_size, RTA_GATEWAY,
 1481:                  &nexthop->gate.ipv4, bytelen);
 1482:       if (nexthop->src.ipv4.s_addr)
 1483:         addattr_l (nlmsg, req_size, RTA_PREFSRC,
 1484:                    &nexthop->src.ipv4, bytelen);
 1485: 
 1486:       if (IS_ZEBRA_DEBUG_KERNEL)
 1487:         zlog_debug("netlink_route_multipath() (%s): "
 1488:                    "nexthop via %s if %u",
 1489:                    routedesc,
 1490:                    inet_ntoa (nexthop->gate.ipv4),
 1491:                    nexthop->ifindex);
 1492:     }
 1493: #ifdef HAVE_IPV6
 1494:   if (nexthop->type == NEXTHOP_TYPE_IPV6
 1495:       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
 1496:       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
 1497:     {
 1498:       addattr_l (nlmsg, req_size, RTA_GATEWAY,
 1499:                  &nexthop->gate.ipv6, bytelen);
 1500: 
 1501:       if (IS_ZEBRA_DEBUG_KERNEL)
 1502:         zlog_debug("netlink_route_multipath() (%s): "
 1503:                    "nexthop via %s if %u",
 1504:                    routedesc,
 1505:                    inet6_ntoa (nexthop->gate.ipv6),
 1506:                    nexthop->ifindex);
 1507:     }
 1508: #endif /* HAVE_IPV6 */
 1509:   if (nexthop->type == NEXTHOP_TYPE_IFINDEX
 1510:       || nexthop->type == NEXTHOP_TYPE_IFNAME
 1511:       || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
 1512:     {
 1513:       addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
 1514: 
 1515:       if (nexthop->src.ipv4.s_addr)
 1516:         addattr_l (nlmsg, req_size, RTA_PREFSRC,
 1517:                    &nexthop->src.ipv4, bytelen);
 1518: 
 1519:       if (IS_ZEBRA_DEBUG_KERNEL)
 1520:         zlog_debug("netlink_route_multipath() (%s): "
 1521:                    "nexthop via if %u", routedesc, nexthop->ifindex);
 1522:     }
 1523: 
 1524:   if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
 1525:       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
 1526:     {
 1527:       addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex);
 1528: 
 1529:       if (IS_ZEBRA_DEBUG_KERNEL)
 1530:         zlog_debug("netlink_route_multipath() (%s): "
 1531:                    "nexthop via if %u", routedesc, nexthop->ifindex);
 1532:     }
 1533: }
 1534: 
 1535: /* This function takes a nexthop as argument and
 1536:  * appends to the given rtattr/rtnexthop pair the
 1537:  * representation of the nexthop. If the nexthop
 1538:  * defines a preferred source, the src parameter
 1539:  * will be modified to point to that src, otherwise
 1540:  * it will be kept unmodified.
 1541:  *
 1542:  * @param routedesc: Human readable description of route type
 1543:  *                   (direct/recursive, single-/multipath)
 1544:  * @param bytelen: Length of addresses in bytes.
 1545:  * @param nexthop: Nexthop information
 1546:  * @param rta: rtnetlink attribute structure
 1547:  * @param rtnh: pointer to an rtnetlink nexthop structure
 1548:  * @param src: pointer pointing to a location where
 1549:  *             the prefsrc should be stored.
 1550:  */
 1551: static void
 1552: _netlink_route_build_multipath(
 1553:         const char *routedesc,
 1554:         int bytelen,
 1555:         struct nexthop *nexthop,
 1556:         struct rtattr *rta,
 1557:         struct rtnexthop *rtnh,
 1558:         union g_addr **src
 1559:         )
 1560: {
 1561:   rtnh->rtnh_len = sizeof (*rtnh);
 1562:   rtnh->rtnh_flags = 0;
 1563:   rtnh->rtnh_hops = 0;
 1564:   rta->rta_len += rtnh->rtnh_len;
 1565: 
 1566:   if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
 1567:     rtnh->rtnh_flags |= RTNH_F_ONLINK;
 1568: 
 1569:   if (nexthop->type == NEXTHOP_TYPE_IPV4
 1570:       || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
 1571:     {
 1572:       rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
 1573:                      &nexthop->gate.ipv4, bytelen);
 1574:       rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
 1575: 
 1576:       if (nexthop->src.ipv4.s_addr)
 1577:         *src = &nexthop->src;
 1578: 
 1579:       if (IS_ZEBRA_DEBUG_KERNEL)
 1580:         zlog_debug("netlink_route_multipath() (%s): "
 1581:                    "nexthop via %s if %u",
 1582:                    routedesc,
 1583:                    inet_ntoa (nexthop->gate.ipv4),
 1584:                    nexthop->ifindex);
 1585:     }
 1586: #ifdef HAVE_IPV6
 1587:   if (nexthop->type == NEXTHOP_TYPE_IPV6
 1588:       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
 1589:       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
 1590:     {
 1591:       rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY,
 1592:                      &nexthop->gate.ipv6, bytelen);
 1593:       rtnh->rtnh_len += sizeof (struct rtattr) + bytelen;
 1594: 
 1595:       if (IS_ZEBRA_DEBUG_KERNEL)
 1596:         zlog_debug("netlink_route_multipath() (%s): "
 1597:                    "nexthop via %s if %u",
 1598:                    routedesc,
 1599:                    inet6_ntoa (nexthop->gate.ipv6),
 1600:                    nexthop->ifindex);
 1601:     }
 1602: #endif /* HAVE_IPV6 */
 1603:   /* ifindex */
 1604:   if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
 1605:       || nexthop->type == NEXTHOP_TYPE_IFINDEX
 1606:       || nexthop->type == NEXTHOP_TYPE_IFNAME)
 1607:     {
 1608:       rtnh->rtnh_ifindex = nexthop->ifindex;
 1609:       if (nexthop->src.ipv4.s_addr)
 1610:         *src = &nexthop->src;
 1611:       if (IS_ZEBRA_DEBUG_KERNEL)
 1612:         zlog_debug("netlink_route_multipath() (%s): "
 1613:                    "nexthop via if %u", routedesc, nexthop->ifindex);
 1614:     }
 1615:   else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
 1616:       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
 1617:     {
 1618:       rtnh->rtnh_ifindex = nexthop->ifindex;
 1619: 
 1620:       if (IS_ZEBRA_DEBUG_KERNEL)
 1621:         zlog_debug("netlink_route_multipath() (%s): "
 1622:                    "nexthop via if %u", routedesc, nexthop->ifindex);
 1623:     }
 1624:   else
 1625:     {
 1626:       rtnh->rtnh_ifindex = 0;
 1627:     }
 1628: }
 1629: 
 1630: /* Log debug information for netlink_route_multipath
 1631:  * if debug logging is enabled.
 1632:  *
 1633:  * @param cmd: Netlink command which is to be processed
 1634:  * @param p: Prefix for which the change is due
 1635:  * @param nexthop: Nexthop which is currently processed
 1636:  * @param routedesc: Semantic annotation for nexthop
 1637:  *                     (recursive, multipath, etc.)
 1638:  * @param family: Address family which the change concerns
 1639:  */
 1640: static void
 1641: _netlink_route_debug(
 1642:         int cmd,
 1643:         struct prefix *p,
 1644:         struct nexthop *nexthop,
 1645:         const char *routedesc,
 1646:         int family,
 1647:         struct zebra_vrf *zvrf)
 1648: {
 1649:   if (IS_ZEBRA_DEBUG_KERNEL)
 1650:     {
 1651:       char buf[PREFIX_STRLEN];
 1652:       zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s",
 1653:          routedesc,
 1654:          lookup (nlmsg_str, cmd),
 1655:          prefix2str (p, buf, sizeof(buf)),
 1656:          zvrf->vrf_id,
 1657:          nexthop_type_to_str (nexthop->type));
 1658:     }
 1659: }
 1660: 
 1661: /* Routing table change via netlink interface. */
 1662: static int
 1663: netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib)
 1664: {
 1665:   int bytelen;
 1666:   struct sockaddr_nl snl;
 1667:   struct nexthop *nexthop = NULL, *tnexthop;
 1668:   int recursing;
 1669:   int nexthop_num;
 1670:   int discard;
 1671:   int family = PREFIX_FAMILY(p);
 1672:   const char *routedesc;
 1673: 
 1674:   struct
 1675:   {
 1676:     struct nlmsghdr n;
 1677:     struct rtmsg r;
 1678:     char buf[NL_PKT_BUF_SIZE];
 1679:   } req;
 1680: 
 1681:   struct zebra_vrf *zvrf = vrf_info_lookup (rib->vrf_id);
 1682: 
 1683:   memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
 1684: 
 1685:   bytelen = (family == AF_INET ? 4 : 16);
 1686: 
 1687:   req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
 1688:   req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REPLACE | NLM_F_REQUEST;
 1689:   req.n.nlmsg_type = cmd;
 1690:   req.r.rtm_family = family;
 1691:   req.r.rtm_table = rib->table;
 1692:   req.r.rtm_dst_len = p->prefixlen;
 1693:   req.r.rtm_protocol = RTPROT_ZEBRA;
 1694:   req.r.rtm_scope = RT_SCOPE_LINK;
 1695: 
 1696:   if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
 1697:     discard = 1;
 1698:   else
 1699:     discard = 0;
 1700: 
 1701:   if (cmd == RTM_NEWROUTE)
 1702:     {
 1703:       if (discard)
 1704:         {
 1705:           if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
 1706:             req.r.rtm_type = RTN_BLACKHOLE;
 1707:           else if (rib->flags & ZEBRA_FLAG_REJECT)
 1708:             req.r.rtm_type = RTN_UNREACHABLE;
 1709:           else
 1710:             assert (RTN_BLACKHOLE != RTN_UNREACHABLE);  /* false */
 1711:         }
 1712:       else
 1713:         req.r.rtm_type = RTN_UNICAST;
 1714:     }
 1715: 
 1716:   addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
 1717: 
 1718:   /* Metric. */
 1719:   addattr32 (&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC);
 1720: 
 1721:   if (rib->mtu || rib->nexthop_mtu)
 1722:     {
 1723:       char buf[NL_PKT_BUF_SIZE];
 1724:       struct rtattr *rta = (void *) buf;
 1725:       u_int32_t mtu = rib->mtu;
 1726:       if (!mtu || (rib->nexthop_mtu && rib->nexthop_mtu < mtu))
 1727:         mtu = rib->nexthop_mtu;
 1728:       rta->rta_type = RTA_METRICS;
 1729:       rta->rta_len = RTA_LENGTH(0);
 1730:       rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTAX_MTU, &mtu, sizeof mtu);
 1731:       addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_METRICS, RTA_DATA (rta),
 1732:                  RTA_PAYLOAD (rta));
 1733:     }
 1734: 
 1735:   if (discard)
 1736:     {
 1737:       if (cmd == RTM_NEWROUTE)
 1738:         for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
 1739:           {
 1740:             /* We shouldn't encounter recursive nexthops on discard routes,
 1741:              * but it is probably better to handle that case correctly anyway.
 1742:              */
 1743:             if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 1744:               continue;
 1745:             SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
 1746:           }
 1747:       goto skip;
 1748:     }
 1749: 
 1750:   /* Count overall nexthops so we can decide whether to use singlepath
 1751:    * or multipath case. */
 1752:   nexthop_num = 0;
 1753:   for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
 1754:     {
 1755:       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 1756:         continue;
 1757:       if (cmd == RTM_NEWROUTE && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
 1758:         continue;
 1759:       if (cmd == RTM_DELROUTE && !CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
 1760:         continue;
 1761: 
 1762:       if (nexthop->type != NEXTHOP_TYPE_IFINDEX &&
 1763:           nexthop->type != NEXTHOP_TYPE_IFNAME)
 1764:         req.r.rtm_scope = RT_SCOPE_UNIVERSE;
 1765: 
 1766:       nexthop_num++;
 1767:     }
 1768: 
 1769:   /* Singlepath case. */
 1770:   if (nexthop_num == 1 || MULTIPATH_NUM == 1)
 1771:     {
 1772:       nexthop_num = 0;
 1773:       for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
 1774:         {
 1775:           if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 1776:             continue;
 1777: 
 1778:           if ((cmd == RTM_NEWROUTE
 1779:                && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
 1780:               || (cmd == RTM_DELROUTE
 1781:                   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
 1782:             {
 1783:               routedesc = recursing ? "recursive, 1 hop" : "single hop";
 1784: 
 1785:               _netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf);
 1786:               _netlink_route_build_singlepath(routedesc, bytelen,
 1787:                                               nexthop, &req.n, &req.r,
 1788:                                               sizeof req);
 1789: 
 1790:               if (cmd == RTM_NEWROUTE)
 1791:                 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
 1792: 
 1793:               nexthop_num++;
 1794:               break;
 1795:             }
 1796:         }
 1797:     }
 1798:   else
 1799:     {
 1800:       char buf[NL_PKT_BUF_SIZE];
 1801:       struct rtattr *rta = (void *) buf;
 1802:       struct rtnexthop *rtnh;
 1803:       union g_addr *src = NULL;
 1804: 
 1805:       rta->rta_type = RTA_MULTIPATH;
 1806:       rta->rta_len = RTA_LENGTH (0);
 1807:       rtnh = RTA_DATA (rta);
 1808: 
 1809:       nexthop_num = 0;
 1810:       for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
 1811:         {
 1812:           if (nexthop_num >= MULTIPATH_NUM)
 1813:             break;
 1814: 
 1815:           if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
 1816:             continue;
 1817: 
 1818:           if ((cmd == RTM_NEWROUTE
 1819:                && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
 1820:               || (cmd == RTM_DELROUTE
 1821:                   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
 1822:             {
 1823:               routedesc = recursing ? "recursive, multihop" : "multihop";
 1824:               nexthop_num++;
 1825: 
 1826:               _netlink_route_debug(cmd, p, nexthop,
 1827:                                    routedesc, family, zvrf);
 1828:               _netlink_route_build_multipath(routedesc, bytelen,
 1829:                                              nexthop, rta, rtnh, &src);
 1830:               rtnh = RTNH_NEXT (rtnh);
 1831: 
 1832:               if (cmd == RTM_NEWROUTE)
 1833:                 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
 1834:             }
 1835:         }
 1836:       if (src)
 1837:         addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src->ipv4, bytelen);
 1838: 
 1839:       if (rta->rta_len > RTA_LENGTH (0))
 1840:         addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta),
 1841:                    RTA_PAYLOAD (rta));
 1842:     }
 1843: 
 1844:   /* If there is no useful nexthop then return. */
 1845:   if (nexthop_num == 0)
 1846:     {
 1847:       if (IS_ZEBRA_DEBUG_KERNEL)
 1848:         zlog_debug ("netlink_route_multipath(): No useful nexthop.");
 1849:       return 0;
 1850:     }
 1851: 
 1852: skip:
 1853: 
 1854:   /* Destination netlink address. */
 1855:   memset (&snl, 0, sizeof snl);
 1856:   snl.nl_family = AF_NETLINK;
 1857: 
 1858:   /* Talk to netlink socket. */
 1859:   return netlink_talk (&req.n, &zvrf->netlink_cmd, zvrf);
 1860: }
 1861: 
 1862: int
 1863: kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
 1864: {
 1865:   if (!old && new)
 1866:     return netlink_route_multipath (RTM_NEWROUTE, p, new);
 1867:   if (old && !new)
 1868:     return netlink_route_multipath (RTM_DELROUTE, p, old);
 1869: 
 1870:    /* Replace, can be done atomically if metric does not change;
 1871:     * netlink uses [prefix, tos, priority] to identify prefix.
 1872:     * Now metric is not sent to kernel, so we can just do atomic replace. */
 1873:   return netlink_route_multipath (RTM_NEWROUTE, p, new);
 1874: }
 1875: 
 1876: /* Interface address modification. */
 1877: static int
 1878: netlink_address (int cmd, int family, struct interface *ifp,
 1879:                  struct connected *ifc)
 1880: {
 1881:   int bytelen;
 1882:   struct prefix *p;
 1883: 
 1884:   struct
 1885:   {
 1886:     struct nlmsghdr n;
 1887:     struct ifaddrmsg ifa;
 1888:     char buf[NL_PKT_BUF_SIZE];
 1889:   } req;
 1890: 
 1891:   struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
 1892: 
 1893:   p = ifc->address;
 1894:   memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
 1895: 
 1896:   bytelen = (family == AF_INET ? 4 : 16);
 1897: 
 1898:   req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
 1899:   req.n.nlmsg_flags = NLM_F_REQUEST;
 1900:   req.n.nlmsg_type = cmd;
 1901:   req.ifa.ifa_family = family;
 1902: 
 1903:   req.ifa.ifa_index = ifp->ifindex;
 1904:   req.ifa.ifa_prefixlen = p->prefixlen;
 1905: 
 1906:   addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
 1907: 
 1908:   if (family == AF_INET && cmd == RTM_NEWADDR)
 1909:     {
 1910:       if (!CONNECTED_PEER(ifc) && ifc->destination)
 1911:         {
 1912:           p = ifc->destination;
 1913:           addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
 1914:                      bytelen);
 1915:         }
 1916:     }
 1917: 
 1918:   if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
 1919:     SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
 1920: 
 1921:   if (ifc->label)
 1922:     addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
 1923:                strlen (ifc->label) + 1);
 1924: 
 1925:   return netlink_talk (&req.n, &zvrf->netlink_cmd, zvrf);
 1926: }
 1927: 
 1928: int
 1929: kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
 1930: {
 1931:   return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
 1932: }
 1933: 
 1934: int
 1935: kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
 1936: {
 1937:   return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
 1938: }
 1939: 
 1940: 
 1941: extern struct thread_master *master;
 1942: 
 1943: /* Kernel route reflection. */
 1944: static int
 1945: kernel_read (struct thread *thread)
 1946: {
 1947:   struct zebra_vrf *zvrf = (struct zebra_vrf *)THREAD_ARG (thread);
 1948:   netlink_parse_info (netlink_information_fetch, &zvrf->netlink, zvrf);
 1949:   zvrf->t_netlink = thread_add_read (zebrad.master, kernel_read, zvrf,
 1950:                                      zvrf->netlink.sock);
 1951: 
 1952:   return 0;
 1953: }
 1954: 
 1955: /* Filter out messages from self that occur on listener socket,
 1956:    caused by our actions on the command socket
 1957:  */
 1958: static void netlink_install_filter (int sock, __u32 pid)
 1959: {
 1960:   struct sock_filter filter[] = {
 1961:     /* 0: ldh [4]	          */
 1962:     BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
 1963:     /* 1: jeq 0x18 jt 3 jf 6  */
 1964:     BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0),
 1965:     /* 2: jeq 0x19 jt 3 jf 6  */
 1966:     BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3),
 1967:     /* 3: ldw [12]		  */
 1968:     BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)),
 1969:     /* 4: jeq XX  jt 5 jf 6   */
 1970:     BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1),
 1971:     /* 5: ret 0    (skip)     */
 1972:     BPF_STMT(BPF_RET|BPF_K, 0),
 1973:     /* 6: ret 0xffff (keep)   */
 1974:     BPF_STMT(BPF_RET|BPF_K, 0xffff),
 1975:   };
 1976: 
 1977:   struct sock_fprog prog = {
 1978:     .len = array_size(filter),
 1979:     .filter = filter,
 1980:   };
 1981: 
 1982:   if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0)
 1983:     zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno));
 1984: }
 1985: 
 1986: /* Exported interface function.  This function simply calls
 1987:    netlink_socket (). */
 1988: void
 1989: kernel_init (struct zebra_vrf *zvrf)
 1990: {
 1991:   unsigned long groups;
 1992: 
 1993:   groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
 1994: #ifdef HAVE_IPV6
 1995:   groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
 1996: #endif /* HAVE_IPV6 */
 1997:   netlink_socket (&zvrf->netlink, groups, zvrf->vrf_id);
 1998:   netlink_socket (&zvrf->netlink_cmd, 0, zvrf->vrf_id);
 1999: 
 2000:   /* Register kernel socket. */
 2001:   if (zvrf->netlink.sock > 0)
 2002:     {
 2003:       /* Only want non-blocking on the netlink event socket */
 2004:       if (fcntl (zvrf->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
 2005:         zlog_err ("Can't set %s socket flags: %s", zvrf->netlink.name,
 2006:                   safe_strerror (errno));
 2007: 
 2008:       /* Set receive buffer size if it's set from command line */
 2009:       if (nl_rcvbufsize)
 2010:         netlink_recvbuf (&zvrf->netlink, nl_rcvbufsize);
 2011: 
 2012:       netlink_install_filter (zvrf->netlink.sock, zvrf->netlink_cmd.snl.nl_pid);
 2013:       zvrf->t_netlink = thread_add_read (zebrad.master, kernel_read, zvrf,
 2014:                                          zvrf->netlink.sock);
 2015:     }
 2016: }
 2017: 
 2018: void
 2019: kernel_terminate (struct zebra_vrf *zvrf)
 2020: {
 2021:   THREAD_READ_OFF (zvrf->t_netlink);
 2022: 
 2023:   if (zvrf->netlink.sock >= 0)
 2024:     {
 2025:       close (zvrf->netlink.sock);
 2026:       zvrf->netlink.sock = -1;
 2027:     }
 2028: 
 2029:   if (zvrf->netlink_cmd.sock >= 0)
 2030:     {
 2031:       close (zvrf->netlink_cmd.sock);
 2032:       zvrf->netlink_cmd.sock = -1;
 2033:     }
 2034: }
 2035: 
 2036: /*
 2037:  * nl_msg_type_to_str
 2038:  */
 2039: const char *
 2040: nl_msg_type_to_str (uint16_t msg_type)
 2041: {
 2042:   return lookup (nlmsg_str, msg_type);
 2043: }
 2044: 
 2045: /*
 2046:  * nl_rtproto_to_str
 2047:  */
 2048: const char *
 2049: nl_rtproto_to_str (u_char rtproto)
 2050: {
 2051:   return lookup (rtproto_str, rtproto);
 2052: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>