[BACK]Return to mpls_routes.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.sbin / ldpd

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/usr.sbin/ldpd/mpls_routes.c between version 1.14 and 1.15

version 1.14, 2013/07/12 08:55:52 version 1.15, 2013/07/16 02:54:32
Line 68  int             replay_index = 0;
Line 68  int             replay_index = 0;
 static int read_route_socket(char *, int);  static int read_route_socket(char *, int);
 void    mask_addr(union sockunion *);  void    mask_addr(union sockunion *);
 int     compare_sockunion(const union sockunion *, const union sockunion *);  int     compare_sockunion(const union sockunion *, const union sockunion *);
 char *  mpls_ntoa(union mpls_shim);  
 static int check_if_addr_updown(struct rt_msg *, uint);  static int check_if_addr_updown(struct rt_msg *, uint);
   
 extern struct sockaddr mplssockaddr;  extern struct sockaddr mplssockaddr;
Line 79  extern struct sockaddr mplssockaddr;
Line 78  extern struct sockaddr mplssockaddr;
         do { l = RT_ROUNDUP(u->sa.sa_len); memcpy(cp, u, l); cp += l;} while(0);          do { l = RT_ROUNDUP(u->sa.sa_len); memcpy(cp, u, l); cp += l;} while(0);
 #define NEXTADDR2(u) \  #define NEXTADDR2(u) \
         do { l = RT_ROUNDUP(u.sa_len); memcpy(cp, &u, l); cp += l; } while(0);          do { l = RT_ROUNDUP(u.sa_len); memcpy(cp, &u, l); cp += l; } while(0);
 #define GETNEXT(sunion) \  
         (union sockunion *) ((char *) (sunion)  + \  #define CHECK_LEN(sunion) \
         RT_ROUNDUP((sunion)->sa.sa_len))          if (size_cp + sunion->sa.sa_len > rlen) \
                   return LDP_E_ROUTE_ERROR; \
           else \
                   size_cp += sunion->sa.sa_len;
   
   #define CHECK_MINSA \
           if (size_cp + sizeof(sa_family_t) + sizeof(uint8_t) > rlen) \
                   return LDP_E_ROUTE_ERROR;
   
   #define GETNEXT(dstunion, origunion) \
           do { \
           CHECK_MINSA \
           dstunion = (union sockunion *) ((char *) (origunion)  + \
           RT_ROUNDUP((origunion)->sa.sa_len)); \
           CHECK_LEN(dstunion) \
           } while (0);
   
   
 static int  static int
 read_route_socket(char *s, int max)  read_route_socket(char *s, int max)
Line 267  from_cidr_to_mask(uint8_t prefixlen, cha
Line 282  from_cidr_to_mask(uint8_t prefixlen, cha
             (a << 16) >> 24, (a << 24) >> 24);              (a << 16) >> 24, (a << 24) >> 24);
 }  }
   
 char *  
 mpls_ntoa(const union mpls_shim ms)  
 {  
         static char     ret[255];  
         union mpls_shim ms2;  
   
         ms2.s_addr = ntohl(ms.s_addr);  
         snprintf(ret, sizeof(ret), "%d", ms2.shim.label);  
         return ret;  
 }  
   
 char *  
 union_ntoa(const union sockunion * so)  
 {  
         static char defret[] = "Unknown family address";  
   
         switch (so->sa.sa_family) {  
         case AF_INET:  
                 return inet_ntoa(so->sin.sin_addr);  
         case AF_LINK:  
                 return link_ntoa(&so->sdl);  
         case AF_MPLS:  
                 return mpls_ntoa(so->smpls.smpls_addr);  
         }  
         fatalp("Unknown family address in union_ntoa: %d\n",  
                so->sa.sa_family);  
         return defret;  
 }  
   
 /* From src/sbin/route/route.c */  /* From src/sbin/route/route.c */
 static const char *  static const char *
 route_strerror(int error)  route_strerror(int error)
Line 386  add_route(union sockunion *so_dest, unio
Line 372  add_route(union sockunion *so_dest, unio
   
         if ((rlen = write(route_socket, (char *) &rm, l)) < l) {          if ((rlen = write(route_socket, (char *) &rm, l)) < l) {
                 warnp("Error adding a route: %s\n", route_strerror(errno));                  warnp("Error adding a route: %s\n", route_strerror(errno));
                 warnp("Destination was: %s\n", union_ntoa(so_dest));                  warnp("Destination was: %s\n", satos(&so_dest->sa));
                 if (so_prefix)                  if (so_prefix)
                         warnp("Prefix was: %s\n", union_ntoa(so_prefix));                          warnp("Prefix was: %s\n", satos(&so_prefix->sa));
                 if (so_gate)                  if (so_gate)
                         warnp("Gateway was: %s\n", union_ntoa(so_gate));                          warnp("Gateway was: %s\n", satos(&so_gate->sa));
                 rv = LDP_E_ROUTE_ERROR;                  rv = LDP_E_ROUTE_ERROR;
         }          }
         if (fr == FREESO) {          if (fr == FREESO) {
Line 461  delete_route(union sockunion * so_dest, 
Line 447  delete_route(union sockunion * so_dest, 
                 strlcpy(spreftmp, inet_ntoa(so_pref->sin.sin_addr),                  strlcpy(spreftmp, inet_ntoa(so_pref->sin.sin_addr),
                     INET_ADDRSTRLEN);                      INET_ADDRSTRLEN);
                 warnp("Error deleting route(%s): %s/%s",                  warnp("Error deleting route(%s): %s/%s",
                     route_strerror(errno), union_ntoa(so_dest),                      route_strerror(errno), satos(&so_dest->sa),
                     spreftmp);                      spreftmp);
             } else              } else
                 warnp("Error deleting route(%s) : %s",                  warnp("Error deleting route(%s) : %s",
                     route_strerror(errno), union_ntoa(so_dest));                      route_strerror(errno), satos(&so_dest->sa));
             return LDP_E_NO_SUCH_ROUTE;              return LDP_E_NO_SUCH_ROUTE;
         }          }
         return LDP_E_OK;          return LDP_E_OK;
Line 559  get_route(struct rt_msg * rg, const unio
Line 545  get_route(struct rt_msg * rg, const unio
         if (exact_match) {          if (exact_match) {
                 su = (union sockunion*)(rg->m_space);                  su = (union sockunion*)(rg->m_space);
                 if (compare_sockunion(so_dest, su)) {                  if (compare_sockunion(so_dest, su)) {
                         debugp("Dest %s ", union_ntoa(so_dest));                          debugp("Dest %s ", satos(&so_dest->sa));
                         debugp("not like %s\n", union_ntoa(su));                          debugp("not like %s\n", satos(&su->sa));
                         return LDP_E_NO_SUCH_ROUTE;                          return LDP_E_NO_SUCH_ROUTE;
                 }                  }
         }          }
Line 575  check_route(struct rt_msg * rg, uint rle
Line 561  check_route(struct rt_msg * rg, uint rle
         union sockunion *so_dest = NULL, *so_gate = NULL, *so_pref = NULL;          union sockunion *so_dest = NULL, *so_gate = NULL, *so_pref = NULL;
         int             so_pref_allocated = 0;          int             so_pref_allocated = 0;
         int             prefixlen;          int             prefixlen;
           size_t          size_cp;
         struct peer_map *pm;          struct peer_map *pm;
         struct label    *lab;          struct label    *lab;
         char            dest[50], gate[50], pref[50], oper[50];          char            dest[50], gate[50], pref[50], oper[50];
Line 589  check_route(struct rt_msg * rg, uint rle
Line 576  check_route(struct rt_msg * rg, uint rle
             rg->m_rtm.rtm_type == RTM_DELADDR)              rg->m_rtm.rtm_type == RTM_DELADDR)
                 return check_if_addr_updown(rg, rlen);                  return check_if_addr_updown(rg, rlen);
   
         if (rlen < sizeof(struct rt_msghdr))          size_cp = sizeof(struct rt_msghdr);
                 return LDP_E_ROUTE_ERROR;          CHECK_MINSA;
   
         if (rg->m_rtm.rtm_pid == getpid() ||          if (rg->m_rtm.rtm_pid == getpid() ||
             ((rg->m_rtm.rtm_flags & RTF_DONE) == 0))              ((rg->m_rtm.rtm_flags & RTF_DONE) == 0))
Line 603  check_route(struct rt_msg * rg, uint rle
Line 590  check_route(struct rt_msg * rg, uint rle
         if (so_dest->sa.sa_family != AF_INET)          if (so_dest->sa.sa_family != AF_INET)
                 return LDP_E_OK;/* We don't care about non-IP changes */                  return LDP_E_OK;/* We don't care about non-IP changes */
   
           CHECK_LEN(so_dest);
   
         if (rg->m_rtm.rtm_addrs & RTA_GATEWAY) {          if (rg->m_rtm.rtm_addrs & RTA_GATEWAY) {
                 so_gate = GETNEXT(so_dest);                  GETNEXT(so_gate, so_dest);
                 if ((so_gate->sa.sa_family != AF_INET) &&                  if ((so_gate->sa.sa_family != AF_INET) &&
                     (so_gate->sa.sa_family != AF_MPLS))                      (so_gate->sa.sa_family != AF_MPLS))
                         return LDP_E_OK;                          return LDP_E_OK;
Line 614  check_route(struct rt_msg * rg, uint rle
Line 603  check_route(struct rt_msg * rg, uint rle
                         so_pref = so_gate;                          so_pref = so_gate;
                 else                  else
                         so_pref = so_dest;                          so_pref = so_dest;
                 so_pref = GETNEXT(so_pref);                  GETNEXT(so_pref, so_pref);
         }          }
         if (!(rg->m_rtm.rtm_flags & RTF_GATEWAY)) {          if (!(rg->m_rtm.rtm_flags & RTF_GATEWAY)) {
                 if (rg->m_rtm.rtm_addrs & RTA_GENMASK) {                  if (rg->m_rtm.rtm_addrs & RTA_GENMASK) {
Line 673  check_route(struct rt_msg * rg, uint rle
Line 662  check_route(struct rt_msg * rg, uint rle
                         }                          }
                 } else  /* We already know about this prefix */                  } else  /* We already know about this prefix */
                         debugp("Binding already there for prefix %s/%d !\n",                          debugp("Binding already there for prefix %s/%d !\n",
                               union_ntoa(so_dest), prefixlen);                                satos(&so_dest->sa), prefixlen);
                 break;                  break;
         case RTM_DELETE:          case RTM_DELETE:
                 if (!so_gate)                  if (!so_gate)
Line 701  check_route(struct rt_msg * rg, uint rle
Line 690  check_route(struct rt_msg * rg, uint rle
         /* Rest is just for debug */          /* Rest is just for debug */
   
         if (so_dest)          if (so_dest)
                 strlcpy(dest, union_ntoa(so_dest), 16);                  strlcpy(dest, satos(&so_dest->sa), sizeof(dest));
         if (so_pref)          if (so_pref)
                 snprintf(pref, 3, "%d", prefixlen);                  snprintf(pref, sizeof(pref), "%d", prefixlen);
         if (so_gate)          if (so_gate)
                 strlcpy(gate, union_ntoa(so_gate), 16);                  strlcpy(gate, satos(&so_gate->sa), sizeof(gate));
   
         switch (rg->m_rtm.rtm_type) {          switch (rg->m_rtm.rtm_type) {
         case RTM_ADD:          case RTM_ADD:
Line 755  check_if_addr_updown(struct rt_msg * rg,
Line 744  check_if_addr_updown(struct rt_msg * rg,
         struct ldp_peer *p;          struct ldp_peer *p;
         struct address_list_tlv al_tlv;          struct address_list_tlv al_tlv;
         struct ifa_msghdr *msghdr = (struct ifa_msghdr *)&rg->m_rtm;          struct ifa_msghdr *msghdr = (struct ifa_msghdr *)&rg->m_rtm;
           size_t size_cp = sizeof(struct ifa_msghdr);
   
         if (rlen < sizeof(struct ifa_msghdr) ||          if (rlen < sizeof(struct ifa_msghdr) ||
             (msghdr->ifam_addrs & RTA_NETMASK) == 0 ||              (msghdr->ifam_addrs & RTA_NETMASK) == 0 ||
             (msghdr->ifam_addrs & RTA_IFA) == 0)              (msghdr->ifam_addrs & RTA_IFA) == 0)
                 return LDP_E_ROUTE_ERROR;                  return LDP_E_ROUTE_ERROR;
   
           CHECK_MINSA;
   
         /* we should have RTA_NETMASK, RTA_IFP, RTA_IFA and RTA_BRD */          /* we should have RTA_NETMASK, RTA_IFP, RTA_IFA and RTA_BRD */
         ifa = netmask = (union sockunion *)(msghdr + 1);          ifa = netmask = (union sockunion *)(msghdr + 1);
         if (netmask->sa.sa_family != AF_INET)          if (netmask->sa.sa_family != AF_INET)
                 return LDP_E_OK;                  return LDP_E_OK;
           CHECK_LEN(netmask);
   
         if (msghdr->ifam_addrs & RTA_IFP)          if (msghdr->ifam_addrs & RTA_IFP)
                 ifa = GETNEXT(ifa);                  GETNEXT(ifa, ifa);
         ifa = GETNEXT(ifa);  
           GETNEXT(ifa, ifa);
   
         if (ifa->sa.sa_family != AF_INET ||          if (ifa->sa.sa_family != AF_INET ||
             ntohl(ifa->sin.sin_addr.s_addr) >> 24 == IN_LOOPBACKNET)              ntohl(ifa->sin.sin_addr.s_addr) >> 24 == IN_LOOPBACKNET)
Line 794  check_if_addr_updown(struct rt_msg * rg,
Line 788  check_if_addr_updown(struct rt_msg * rg,
 int  int
 bind_current_routes()  bind_current_routes()
 {  {
         size_t          needed;          size_t          needed, size_cp;
         int             mib[6];          int             mib[6];
         char           *buf, *next, *lim;          char           *buf, *next, *lim;
         struct rt_msghdr *rtmes;          struct rt_msghdr *rtmes;
         union sockunion *so_dst, *so_pref, *so_gate;          union sockunion *so_dst, *so_pref, *so_gate;
           uint rlen;
   
         mib[0] = CTL_NET;          mib[0] = CTL_NET;
         mib[1] = PF_ROUTE;          mib[1] = PF_ROUTE;
Line 819  bind_current_routes()
Line 814  bind_current_routes()
         }          }
         lim = buf + needed;          lim = buf + needed;
   
         for (next = buf; next < lim; next += rtmes->rtm_msglen) {          for (next = buf; next < lim; next += rlen) {
                 rtmes = (struct rt_msghdr *) next;                  rtmes = (struct rt_msghdr *) next;
                   rlen = rtmes->rtm_msglen;
                   size_cp = sizeof(struct rt_msghdr);
                 so_pref = NULL;                  so_pref = NULL;
                 so_gate = NULL;                  so_gate = NULL;
                 if (rtmes->rtm_flags & RTF_LLINFO)      /* No need for arps */                  if (rtmes->rtm_flags & RTF_LLINFO)      /* No need for arps */
Line 830  bind_current_routes()
Line 827  bind_current_routes()
                         continue;                          continue;
                 }                  }
   
                   CHECK_MINSA;
                 so_dst = (union sockunion *) & rtmes[1];                  so_dst = (union sockunion *) & rtmes[1];
                   CHECK_LEN(so_dst);
                 /*                  /*
                  * This function is called only at startup, so use                   * This function is called only at startup, so use
                  * this ocassion to delete all MPLS routes                   * this ocassion to delete all MPLS routes
Line 851  bind_current_routes()
Line 849  bind_current_routes()
                 if (so_dst->sin.sin_addr.s_addr == 0 && no_default_route != 0)                  if (so_dst->sin.sin_addr.s_addr == 0 && no_default_route != 0)
                         continue;                          continue;
   
                 /* XXX: Check if it's loopback */                  /* Check if it's loopback */
                 if ((ntohl(so_dst->sin.sin_addr.s_addr) >> 24)==IN_LOOPBACKNET)                  if ((ntohl(so_dst->sin.sin_addr.s_addr) >> 24)==IN_LOOPBACKNET)
                         continue;                          continue;
   
                 /* Get Gateway */                  /* Get Gateway */
                 if (rtmes->rtm_addrs & RTA_GATEWAY)                  if (rtmes->rtm_addrs & RTA_GATEWAY)
                         so_gate = GETNEXT(so_dst);                          GETNEXT(so_gate, so_dst);
   
                 /* Get prefix */                  /* Get prefix */
                 if (rtmes->rtm_flags & RTF_HOST) {                  if (rtmes->rtm_flags & RTF_HOST) {
                         if ((so_pref = from_cidr_to_union(32)) == NULL)                          if ((so_pref = from_cidr_to_union(32)) == NULL)
                                 return LDP_E_MEMORY;                                  return LDP_E_MEMORY;
                 } else if (rtmes->rtm_addrs & RTA_GATEWAY)                  } else if (rtmes->rtm_addrs & RTA_GATEWAY) {
                         so_pref = GETNEXT(so_gate);                          GETNEXT(so_pref, so_gate);
                 else                  } else
                         so_pref = GETNEXT(so_dst);                          GETNEXT(so_pref, so_dst);
   
                 so_pref->sa.sa_family = AF_INET;                  so_pref->sa.sa_family = AF_INET;
                 so_pref->sa.sa_len = sizeof(struct sockaddr_in);                  so_pref->sa.sa_len = sizeof(struct sockaddr_in);
Line 895  bind_current_routes()
Line 893  bind_current_routes()
 int  int
 flush_mpls_routes()  flush_mpls_routes()
 {  {
         size_t          needed;          size_t needed, size_cp;
         int             mib[6];          int mib[6];
         char           *buf, *next, *lim;          uint rlen;
           char *buf, *next, *lim;
         struct rt_msghdr *rtm;          struct rt_msghdr *rtm;
         union sockunion *so_dst, *so_pref, *so_gate;          union sockunion *so_dst, *so_pref, *so_gate;
   
Line 921  flush_mpls_routes()
Line 920  flush_mpls_routes()
         }          }
         lim = buf + needed;          lim = buf + needed;
   
         for (next = buf; next < lim; next += rtm->rtm_msglen) {          for (next = buf; next < lim; next += rlen) {
                 rtm = (struct rt_msghdr *) next;                  rtm = (struct rt_msghdr *) next;
                   size_cp = sizeof(struct rt_msghdr);
                   rlen = rtm->rtm_msglen;
                 so_pref = NULL;                  so_pref = NULL;
                 so_gate = NULL;                  so_gate = NULL;
                 if (rtm->rtm_flags & RTF_LLINFO)        /* No need for arps */                  if (rtm->rtm_flags & RTF_LLINFO)        /* No need for arps */
Line 940  flush_mpls_routes()
Line 941  flush_mpls_routes()
                 }                  }
   
                 if (rtm->rtm_addrs & RTA_GATEWAY) {                  if (rtm->rtm_addrs & RTA_GATEWAY) {
                         so_gate = GETNEXT(so_dst);                          GETNEXT(so_gate, so_dst);
                         so_pref = GETNEXT(so_gate);                          GETNEXT(so_pref, so_gate);
                 } else                  } else
                         so_pref = GETNEXT(so_dst);                          GETNEXT(so_pref, so_dst);
   
                 if (so_gate->sa.sa_family == AF_MPLS) {                  if (so_gate->sa.sa_family == AF_MPLS) {
                         if (so_dst->sa.sa_family == AF_INET)                          if (so_dst->sa.sa_family == AF_INET)

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

CVSweb <webmaster@jp.NetBSD.org>