On Sat, Dec 22, 2018 at 11:42:36PM +0100, Klemens Nanni wrote:
> I have no clue about MPLS, so this feedback is code-wise only:
> 
> Did you consider using more AF agnostic code for parsing the IP address?
> 

You are right, it is simpler. Thank you for the clue :)

Updated diff :

Index: ifconfig.8
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.324
diff -u -p -r1.324 ifconfig.8
--- ifconfig.8  16 Nov 2018 12:25:29 -0000      1.324
+++ ifconfig.8  23 Dec 2018 09:25:36 -0000
@@ -1344,7 +1344,7 @@ is another 20-bit number which will be u
 Sets the destination address where this mpw should output.
 The
 .Ar dest-address
-is an IPv4 address that will be used to find the nexthop in the MPLS
+is an IPv4 or IPv6 address that will be used to find the nexthop in the MPLS
 network.
 .El
 .Sh PAIR
Index: ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.387
diff -u -p -r1.387 ifconfig.c
--- ifconfig.c  29 Nov 2018 00:12:34 -0000      1.387
+++ ifconfig.c  23 Dec 2018 09:25:36 -0000
@@ -3802,8 +3802,9 @@ mpe_status(void)
 void
 mpw_status(void)
 {
-       struct sockaddr_in *sin;
-       struct ifmpwreq imr;
+       struct sockaddr_storage *ss;
+       struct ifmpwreq          imr;
+       char                     hbuf[NI_MAXHOST];
 
        bzero(&imr, sizeof(imr));
        ifr.ifr_data = (caddr_t) &imr;
@@ -3842,11 +3843,19 @@ mpw_status(void)
        else
                printf("remote %u\n", imr.imr_rshim.shim_label);
 
-       sin = (struct sockaddr_in *) &imr.imr_nexthop;
-       if (sin->sin_addr.s_addr == 0)
-               printf("\tneighbor: none\n");
-       else
-               printf("\tneighbor: %s\n", inet_ntoa(sin->sin_addr));
+       printf("\tneighbor: ");
+       switch (imr.imr_nexthop.ss_family) {
+       case AF_INET6:
+       case AF_INET:
+               ss = (struct sockaddr_storage *) &imr.imr_nexthop;
+               if (getnameinfo((struct sockaddr *)ss, ss->ss_len, hbuf,
+                   sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
+                       strlcpy(hbuf, "???", sizeof(hbuf));
+               printf("%s\n", hbuf);
+               break;
+       default:
+               printf("none\n");
+       }
 }
 
 /* ARGSUSED */
@@ -3870,6 +3879,7 @@ void
 process_mpw_commands(void)
 {
        struct  sockaddr_in *sin, *sinn;
+       struct  sockaddr_in6 *sin6, *sin6n;
        struct  ifmpwreq imr;
 
        if (wconfig == 0)
@@ -3899,14 +3909,29 @@ process_mpw_commands(void)
                imrsave.imr_rshim.shim_label = imr.imr_rshim.shim_label;
        }
 
-       sin = (struct sockaddr_in *) &imrsave.imr_nexthop;
-       sinn = (struct sockaddr_in *) &imr.imr_nexthop;
-       if (sin->sin_addr.s_addr == 0) {
-               if (sinn->sin_addr.s_addr == 0)
+       switch (imrsave.imr_nexthop.ss_family) {
+       case AF_INET6:
+       case AF_INET:
+               /* neighbor was set earlier, nothing to do */
+               break;
+       default:
+               switch (imr.imr_nexthop.ss_family) {
+               case AF_INET6:
+                       sin6 = (struct sockaddr_in6 *) &imrsave.imr_nexthop;
+                       sin6n = (struct sockaddr_in6 *) &imr.imr_nexthop;
+                       sin6->sin6_family = sin6n->sin6_family;
+                       memcpy(&sin6->sin6_addr, &sin6n->sin6_addr,
+                           sizeof(struct in6_addr));
+                       break;
+               case AF_INET:
+                       sin = (struct sockaddr_in *) &imrsave.imr_nexthop;
+                       sinn = (struct sockaddr_in *) &imr.imr_nexthop;
+                       sin->sin_family = sinn->sin_family;
+                       sin->sin_addr.s_addr = sinn->sin_addr.s_addr;
+                       break;
+               default:
                        errx(1, "mpw neighbor address not specified");
-
-               sin->sin_family = sinn->sin_family;
-               sin->sin_addr.s_addr = sinn->sin_addr.s_addr;
+               }
        }
 
        ifr.ifr_data = (caddr_t) &imrsave;
@@ -3949,14 +3974,41 @@ void
 setmpwneighbor(const char *value, int d)
 {
        struct sockaddr_in *sin;
+       struct sockaddr_in6 *sin6;
+       struct addrinfo hints, *res;
+       int rv;
 
        wconfig = 1;
 
-       sin = (struct sockaddr_in *) &imrsave.imr_nexthop;
-       if (inet_aton(value, &sin->sin_addr) == 0)
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+       hints.ai_protocol = 0;
+       hints.ai_flags = AI_PASSIVE;
+
+       rv = getaddrinfo(value, NULL, &hints, &res);
+       if (rv != 0)
+               errx(1, "neighbor %s: %s", value, gai_strerror(rv));
+
+       switch (res->ai_family) {
+       case AF_INET:
+               sin = (struct sockaddr_in *) &imrsave.imr_nexthop;
+               sin->sin_family = res->ai_family;
+               sin->sin_addr.s_addr =
+                   ((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr;
+               break;
+       case AF_INET6:
+               sin6 = (struct sockaddr_in6 *) &imrsave.imr_nexthop;
+               sin6->sin6_family = res->ai_family;
+               memcpy(&sin6->sin6_addr,
+                   &((struct sockaddr_in6*)res->ai_addr)->sin6_addr,
+                   sizeof(struct in6_addr));
+               break;
+       default:
                errx(1, "invalid neighbor addresses");
+       }
 
-       sin->sin_family = AF_INET;
+       freeaddrinfo(res);
 }
 
 void

Reply via email to