From 7ab62c5319bd86a3cfda32351bc4103cf9517f26 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 17 May 2007 15:00:41 +0000 Subject: [PtP] Fix BSD problems with PtP interfaces: must treat RTA_BRD as peer address 2007-05-17 Andrew J. Schorr * kernel_socket.c: (ifam_read_mesg) Grab RTA_DST and RTA_GATEWAY addresses from the message (if present, which seems unlikely on current BSD platforms), and show them in the debug messages. Also, add ifam_flags to the debug messages. (ifam_read) If the interface is point-to-point, then the RTA_BRD address should be treated as a peer address. --- zebra/ChangeLog | 9 +++++++++ zebra/kernel_socket.c | 50 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/zebra/ChangeLog b/zebra/ChangeLog index c08bbe4e..b0e8fad6 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -1,3 +1,12 @@ +2007-05-17 Andrew J. Schorr + + * kernel_socket.c: (ifam_read_mesg) Grab RTA_DST and RTA_GATEWAY + addresses from the message (if present, which seems unlikely on + current BSD platforms), and show them in the debug messages. + Also, add ifam_flags to the debug messages. + (ifam_read) If the interface is point-to-point, then the RTA_BRD + address should be treated as a peer address. + 2007-05-01 David L Stevens * (general) These changes collectively add route-map and diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 795ed55f..7bc1b0f9 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -494,6 +494,8 @@ ifam_read_mesg (struct ifa_msghdr *ifm, short *ifnlen) { caddr_t pnt, end; + union sockunion dst; + union sockunion gateway; pnt = (caddr_t)(ifm + 1); end = ((caddr_t)ifm) + ifm->ifam_msglen; @@ -502,10 +504,12 @@ ifam_read_mesg (struct ifa_msghdr *ifm, memset (mask, 0, sizeof (union sockunion)); memset (addr, 0, sizeof (union sockunion)); memset (brd, 0, sizeof (union sockunion)); + memset (&dst, 0, sizeof (union sockunion)); + memset (&gateway, 0, sizeof (union sockunion)); /* We fetch each socket variable into sockunion. */ - RTA_ADDR_GET (NULL, RTA_DST, ifm->ifam_addrs, pnt); - RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifam_addrs, pnt); + RTA_ADDR_GET (&dst, RTA_DST, ifm->ifam_addrs, pnt); + RTA_ADDR_GET (&gateway, RTA_GATEWAY, ifm->ifam_addrs, pnt); RTA_ATTR_GET (mask, RTA_NETMASK, ifm->ifam_addrs, pnt); RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifam_addrs, pnt); RTA_NAME_GET (ifname, RTA_IFP, ifm->ifam_addrs, pnt, *ifnlen); @@ -519,31 +523,43 @@ ifam_read_mesg (struct ifa_msghdr *ifm, { case AF_INET: { - char buf[2][INET_ADDRSTRLEN]; + char buf[4][INET_ADDRSTRLEN]; zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " - "addr %s/%d broad %s", - __func__, ifm->ifam_index, + "ifam_flags 0x%x, addr %s/%d broad %s dst %s " + "gateway %s", + __func__, ifm->ifam_index, (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, + ifm->ifam_flags, inet_ntop(AF_INET,&addr->sin.sin_addr, buf[0],sizeof(buf[0])), ip_masklen(mask->sin.sin_addr), inet_ntop(AF_INET,&brd->sin.sin_addr, - buf[1],sizeof(buf[1]))); + buf[1],sizeof(buf[1])), + inet_ntop(AF_INET,&dst.sin.sin_addr, + buf[2],sizeof(buf[2])), + inet_ntop(AF_INET,&gateway.sin.sin_addr, + buf[3],sizeof(buf[3]))); } break; #ifdef HAVE_IPV6 case AF_INET6: { - char buf[2][INET6_ADDRSTRLEN]; + char buf[4][INET6_ADDRSTRLEN]; zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " - "addr %s/%d broad %s", + "ifam_flags 0x%x, addr %s/%d broad %s dst %s " + "gateway %s", __func__, ifm->ifam_index, (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, + ifm->ifam_flags, inet_ntop(AF_INET6,&addr->sin6.sin6_addr, buf[0],sizeof(buf[0])), ip6_masklen(mask->sin6.sin6_addr), inet_ntop(AF_INET6,&brd->sin6.sin6_addr, - buf[1],sizeof(buf[1]))); + buf[1],sizeof(buf[1])), + inet_ntop(AF_INET6,&dst.sin6.sin6_addr, + buf[2],sizeof(buf[2])), + inet_ntop(AF_INET6,&gateway.sin6.sin6_addr, + buf[3],sizeof(buf[3]))); } break; #endif /* HAVE_IPV6 */ @@ -554,7 +570,7 @@ ifam_read_mesg (struct ifa_msghdr *ifm, break; } } - + /* Assert read up end point matches to end point */ if (pnt != end) zlog_warn ("ifam_read() does't read all socket data"); @@ -569,6 +585,7 @@ ifam_read (struct ifa_msghdr *ifam) char ifname[INTERFACE_NAMSIZ]; short ifnlen = 0; char isalias = 0; + int flags = 0; ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0'; @@ -585,6 +602,12 @@ ifam_read (struct ifa_msghdr *ifam) if (ifnlen && strncmp (ifp->name, ifname, INTERFACE_NAMSIZ)) isalias = 1; + /* N.B. The info in ifa_msghdr does not tell us whether the RTA_BRD + field contains a broadcast address or a peer address, so we are forced to + rely upon the interface type. */ + if (if_is_pointopoint(ifp)) + SET_FLAG(flags, ZEBRA_IFA_PEER); + #if 0 /* it might seem cute to grab the interface metric here, however * we're processing an address update message, and so some systems @@ -599,12 +622,12 @@ ifam_read (struct ifa_msghdr *ifam) { case AF_INET: if (ifam->ifam_type == RTM_NEWADDR) - connected_add_ipv4 (ifp, 0, &addr.sin.sin_addr, + connected_add_ipv4 (ifp, flags, &addr.sin.sin_addr, ip_masklen (mask.sin.sin_addr), &brd.sin.sin_addr, (isalias ? ifname : NULL)); else - connected_delete_ipv4 (ifp, 0, &addr.sin.sin_addr, + connected_delete_ipv4 (ifp, flags, &addr.sin.sin_addr, ip_masklen (mask.sin.sin_addr), &brd.sin.sin_addr); break; @@ -616,8 +639,7 @@ ifam_read (struct ifa_msghdr *ifam) SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0); if (ifam->ifam_type == RTM_NEWADDR) - connected_add_ipv6 (ifp, 0, - &addr.sin6.sin6_addr, + connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr, ip6_masklen (mask.sin6.sin6_addr), &brd.sin6.sin6_addr, (isalias ? ifname : NULL)); -- cgit v1.2.1