From: Ondrej Zajicek Date: Wed, 31 Jul 2013 14:16:48 +0000 (+0200) Subject: Merge commit '6ac4f87a2d661c739e55a63577e7bccf696c7abd' into integrated X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6abc22f4b0cc0b1bd226d04ab3a4f8f59cd1f8d6;p=thirdparty%2Fbird.git Merge commit '6ac4f87a2d661c739e55a63577e7bccf696c7abd' into integrated Conflicts: lib/socket.h proto/ospf/config.Y proto/ospf/iface.c proto/ospf/ospf.h proto/rip/rip.c sysdep/bsd/sysio.h sysdep/linux/sysio.h sysdep/unix/io.c --- 6abc22f4b0cc0b1bd226d04ab3a4f8f59cd1f8d6 diff --cc lib/socket.h index a68ef490e,6e0a769bb..5f642fc90 --- a/lib/socket.h +++ b/lib/socket.h @@@ -89,10 -86,10 +89,11 @@@ extern int sk_priority_control; /* Sugg /* Socket flags */ - #define SKF_V4ONLY 1 /* Use IPv4 for IP sockets */ - #define SKF_V6ONLY 2 /* Use IPV6_V6ONLY socket option */ - #define SKF_LADDR_RX 4 /* Report local address for RX packets */ - #define SKF_LADDR_TX 6 /* Allow to specify local address for TX packets */ -#define SKF_V6ONLY 1 /* Use IPV6_V6ONLY socket option */ -#define SKF_LADDR_RX 2 /* Report local address for RX packets */ -#define SKF_LADDR_TX 4 /* Allow to specify local address for TX packets */ -#define SKF_TTL_RX 8 /* Report TTL / Hop Limit for RX packets */ ++#define SKF_V4ONLY 0x01 /* Use IPv4 for IP sockets */ ++#define SKF_V6ONLY 0x02 /* Use IPV6_V6ONLY socket option */ ++#define SKF_LADDR_RX 0x04 /* Report local address for RX packets */ ++#define SKF_LADDR_TX 0x08 /* Allow to specify local address for TX packets */ ++#define SKF_TTL_RX 0x10 /* Report TTL / Hop Limit for RX packets */ /* diff --cc proto/ospf/config.Y index 2350deaf1,f042e1aa2..ea186ea1d --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@@ -297,7 -307,9 +297,9 @@@ ospf_iface_item | RX BUFFER expr { OSPF_PATT->rxbuf = $3 ; if (($3 < OSPF_RXBUF_MINSIZE) || ($3 > OSPF_MAX_PKT_SIZE)) cf_error("Buffer size must be in range 256-65535"); } | TX tos { OSPF_PATT->tx_tos = $2; } | TX PRIORITY expr { OSPF_PATT->tx_priority = $3; } + | TTL SECURITY bool { OSPF_PATT->ttl_security = $3; } + | TTL SECURITY TX ONLY { OSPF_PATT->ttl_security = 2; } - | password_list + | password_list { ospf_check_auth(); } ; pref_list: diff --cc proto/ospf/iface.c index 7164a4a0e,698ef6208..448b08d11 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@@ -132,9 -130,8 +132,9 @@@ ospf_sk_open(struct ospf_iface *ifa } else { - ifa->all_routers = AllSPFRouters; + ifa->all_routers = ospf_is_v2(po) ? IP4_OSPF_ALL_ROUTERS : IP6_OSPF_ALL_ROUTERS; + ifa->des_routers = ospf_is_v2(po) ? IP4_OSPF_DES_ROUTERS : IP6_OSPF_DES_ROUTERS; - sk->ttl = 1; /* Hack, this will affect just the multicast packets */ + sk->ttl = ifa->cf->ttl_security ? 255 : 1; if (sk_setup_multicast(sk) < 0) goto err; @@@ -535,10 -534,11 +535,11 @@@ ospf_iface_new(struct ospf_area *oa, st ifa->rxbuf = ip->rxbuf; ifa->check_link = ip->check_link; ifa->ecmp_weight = ip->ecmp_weight; + ifa->check_ttl = (ip->ttl_security == 1); - -#ifdef OSPFv2 ifa->autype = ip->autype; ifa->passwords = ip->passwords; + ifa->instance_id = ip->instance_id; + ifa->ptp_netmask = addr ? !(addr->flags & IA_PEER) : 0; if (ip->ptp_netmask < 2) ifa->ptp_netmask = ip->ptp_netmask; diff --cc proto/ospf/ospf.h index d6b97ebf1,f1409af34..55331697c --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@@ -754,9 -816,16 +755,10 @@@ struct ospf_iface_pat u8 check_link; u8 ecmp_weight; u8 real_bcast; /* Not really used in OSPFv3 */ - u8 ptp_netmask; /* bool but 2 for unspecified */ + u8 ptp_netmask; /* bool + 2 for unspecified */ + u8 ttl_security; /* bool + 2 for TX only */ - -#ifdef OSPFv2 - list *passwords; -#endif - -#ifdef OSPFv3 u8 instance_id; -#endif + list *passwords; }; int ospf_import_control(struct proto *p, rte **new, ea_list **attrs, diff --cc proto/rip/config.Y index 4b57a9bf1,791c43a2c..57e291cba --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@@ -22,12 -22,18 +22,15 @@@ CF_DEFINE #define RIP_CFG ((struct rip_proto_config *) this_proto) #define RIP_IPATT ((struct rip_patt *) this_ipatt) -#ifdef IPV6 -#define RIP_DEFAULT_TTL_SECURITY 2 -#else -#define RIP_DEFAULT_TTL_SECURITY 0 -#endif ++static inline int rip_cfg_is_old(void) { return RIP_CFG->c.protocol == &proto_rip; } ++static inline int rip_cfg_is_ng(void) { return RIP_CFG->c.protocol == &proto_ripng; } + CF_DECLS -CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGE, TIMEOUT, +CF_KEYWORDS(RIP, RIPNG, INFINITY, METRIC, PORT, PERIOD, GARBAGE, TIMEOUT, MODE, BROADCAST, MULTICAST, QUIET, NOLISTEN, VERSION1, - AUTHENTICATION, NONE, PLAINTEXT, MD5, - HONOR, NEVER, NEIGHBOR, ALWAYS, TX, PRIORITY, + AUTHENTICATION, NONE, PLAINTEXT, MD5, TTL, SECURITY, + HONOR, NEVER, NEIGHBOR, ALWAYS, TX, PRIORITY, ONLY, RIP_METRIC, RIP_TAG) %type rip_mode rip_auth @@@ -107,6 -106,7 +112,7 @@@ rip_iface_init RIP_IPATT->metric = 1; RIP_IPATT->tx_tos = IP_PREC_INTERNET_CONTROL; RIP_IPATT->tx_priority = sk_priority_control; - RIP_IPATT->ttl_security = RIP_DEFAULT_TTL_SECURITY; ++ RIP_IPATT->ttl_security = rip_cfg_is_ng() ? 1 : 0; } ; diff --cc proto/rip/rip.c index f59487ddd,3ec070b3e..40b9789f9 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@@ -479,10 -478,18 +479,18 @@@ rip_rx(sock *s, int size return 1; iface = i->iface; -#endif + + if (i->check_ttl && (s->ttl < 255)) + { + log( L_REMOTE "%s: Discarding packet with TTL %d (< 255) from %I on %s", + p->name, s->ttl, s->faddr, i->iface->name); + return 1; + } + + CHK_MAGIC; - DBG( "RIP: message came: %d bytes from %I via %s\n", size, s->faddr, i->iface ? i->iface->name : "(dummy)" ); + DBG( "RIP: message came: %d bytes from %I via %s\n", size, s->faddr, iface ? iface->name : "(dummy)" ); size -= sizeof( struct rip_packet_heading ); if (size < 0) BAD( "Too small packet" ); if (size % sizeof( struct rip_block )) BAD( "Odd sized packet" ); @@@ -705,13 -713,12 +714,13 @@@ new_iface(struct proto *p, struct ifac rif->sock->err_hook = rip_tx_err; rif->sock->daddr = IPA_NONE; rif->sock->dport = P_CF->port; + rif->sock->flags = rip_is_old(p) ? SKF_V4ONLY : SKF_V6ONLY; if (new) { - rif->sock->ttl = 1; rif->sock->tos = PATT->tx_tos; rif->sock->priority = PATT->tx_priority; - rif->sock->flags |= SKF_LADDR_RX; + rif->sock->ttl = PATT->ttl_security ? 255 : 1; - rif->sock->flags = SKF_LADDR_RX | (rif->check_ttl ? SKF_TTL_RX : 0); ++ rif->sock->flags |= SKF_LADDR_RX | (rif->check_ttl ? SKF_TTL_RX : 0); } if (new) { diff --cc sysdep/bsd/sysio.h index 3506f56fc,031eac9af..e33bc9c66 --- a/sysdep/bsd/sysio.h +++ b/sysdep/bsd/sysio.h @@@ -81,43 -113,69 +81,57 @@@ sk_leave_group4(sock *s, ip_addr maddr /* BSD RX/TX packet info handling for IPv4 */ /* it uses IP_RECVDSTADDR / IP_RECVIF socket options instead of IP_PKTINFO */ - #define CMSG_RX_SPACE (CMSG_SPACE(sizeof(struct in_addr)) + CMSG_SPACE(sizeof(struct sockaddr_dl))) -#define CMSG_RX_SPACE (CMSG_SPACE(sizeof(struct in_addr)) + \ - CMSG_SPACE(sizeof(struct sockaddr_dl)) + \ - CMSG_SPACE(sizeof(char))) --#define CMSG_TX_SPACE CMSG_SPACE(sizeof(struct in_addr)) ++#define CMSG_SPACE_PKTINFO4 (CMSG_SPACE(sizeof(struct in_addr)) + \ ++ CMSG_SPACE(sizeof(struct sockaddr_dl))) ++#define CMSG_SPACE_PKTINFO6 CMSG_SPACE(sizeof(struct in6_pktinfo)) --static char * - sk_request_pktinfo4(sock *s) -sysio_register_cmsgs(sock *s) ++#define CMSG_RX_SPACE (MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6) + CMSG_SPACE(sizeof(int))) ++#define CMSG_TX_SPACE MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6) ++ ++ ++static inline char * ++sk_request_cmsg4_pktinfo(sock *s) { int ok = 1; -- if (s->flags & SKF_LADDR_RX) - { - if (setsockopt(s->fd, IPPROTO_IP, IP_RECVDSTADDR, &ok, sizeof(ok)) < 0) - return "IP_RECVDSTADDR"; - { - if (setsockopt(s->fd, IPPROTO_IP, IP_RECVDSTADDR, &ok, sizeof(ok)) < 0) - return "IP_RECVDSTADDR"; - if (setsockopt(s->fd, IPPROTO_IP, IP_RECVIF, &ok, sizeof(ok)) < 0) - return "IP_RECVIF"; - } - if (setsockopt(s->fd, IPPROTO_IP, IP_RECVIF, &ok, sizeof(ok)) < 0) - return "IP_RECVIF"; - } - - if ((s->flags & SKF_TTL_RX) && - (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0)) - return "IP_RECVTTL"; ++ if (setsockopt(s->fd, IPPROTO_IP, IP_RECVDSTADDR, &ok, sizeof(ok)) < 0) ++ return "IP_RECVDSTADDR"; + ++ if (setsockopt(s->fd, IPPROTO_IP, IP_RECVIF, &ok, sizeof(ok)) < 0) ++ return "IP_RECVIF"; return NULL; } --static void - sk_process_rx_cmsg4(sock *s, struct cmsghdr *cm) -sysio_process_rx_cmsgs(sock *s, struct msghdr *msg) ++static inline void ++sk_process_cmsg4_pktinfo(sock *s, struct cmsghdr *cm) + { - struct cmsghdr *cm; - struct in_addr *ra = NULL; - struct sockaddr_dl *ri = NULL; - unsigned char *ttl = NULL; - - for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm)) - { - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVDSTADDR) - ra = (struct in_addr *) CMSG_DATA(cm); ++ if ((cm->cmsg_type == IP_RECVDSTADDR) && (s->flags & SKF_LADDR_RX)) ++ s->laddr = ipa_get_in4((struct in_addr *) CMSG_DATA(cm)); + - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF) - ri = (struct sockaddr_dl *) CMSG_DATA(cm); - - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVTTL) - ttl = (unsigned char *) CMSG_DATA(cm); - } ++ if ((cm->cmsg_type == IP_RECVIF) && (s->flags & SKF_LADDR_RX)) ++ s->lifindex = ((struct sockaddr_dl *) CMSG_DATA(cm))->sdl_index; ++} + - if (s->flags & SKF_LADDR_RX) - { - s->laddr = IPA_NONE; - s->lifindex = 0; ++static inline char * ++sk_request_cmsg4_ttl(sock *s) +{ - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVDSTADDR) - { - struct in_addr *ra = (struct in_addr *) CMSG_DATA(cm); - s->laddr = ipa_get_in4(ra); - } - - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF) - { - struct sockaddr_dl *ri = (struct sockaddr_dl *) CMSG_DATA(cm); - s->lifindex = ri->sdl_index; - } - - // log(L_WARN "RX %I %d", s->laddr, s->lifindex); ++ int ok = 1; + - if (ra) - get_inaddr(&s->laddr, ra); - if (ri) - s->lifindex = ri->sdl_index; - } ++ if (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0) ++ return "IP_RECVTTL"; + - if (s->flags & SKF_TTL_RX) - s->ttl = ttl ? *ttl : -1; ++ return NULL; +} - // log(L_WARN "RX %I %d", s->laddr, s->lifindex); ++static inline void ++sk_process_cmsg4_ttl(sock *s, struct cmsghdr *cm) ++{ ++ if ((cm->cmsg_type == IP_RECVTTL) && (s->flags & SKF_TTL_RX)) ++ s->ttl = * (unsigned char *) CMSG_DATA(cm); + } + ++ /* Unfortunately, IP_SENDSRCADDR does not work for raw IP sockets on BSD kernels */ /* static void diff --cc sysdep/linux/sysio.h index 13f3713e4,250ed5866..8c52d8681 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@@ -157,34 -192,63 +157,52 @@@ sk_set_md5_auth_int(sock *s, struct soc /* RX/TX packet info handling for IPv4 */ /* Mostly similar to standardized IPv6 code */ - #define CMSG_SPACE_PKTINFO4 CMSG_SPACE(sizeof(struct in_pktinfo)) - #define CMSG_SPACE_PKTINFO6 CMSG_SPACE(sizeof(struct in6_pktinfo)) -#define CMSG_RX_SPACE (CMSG_SPACE(sizeof(struct in_pktinfo)) + CMSG_SPACE(sizeof(int))) -#define CMSG_TX_SPACE CMSG_SPACE(sizeof(struct in_pktinfo)) ++#define CMSG4_SPACE_PKTINFO CMSG_SPACE(sizeof(struct in_pktinfo)) - #define CMSG_RX_SPACE MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6) - #define CMSG_TX_SPACE MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6) -static char * -sysio_register_cmsgs(sock *s) ++static inline char * ++sk_request_cmsg4_pktinfo(sock *s) + { + int ok = 1; + - if ((s->flags & SKF_LADDR_RX) && - (setsockopt(s->fd, IPPROTO_IP, IP_PKTINFO, &ok, sizeof(ok)) < 0)) ++ if (setsockopt(s->fd, IPPROTO_IP, IP_PKTINFO, &ok, sizeof(ok)) < 0) + return "IP_PKTINFO"; + - if ((s->flags & SKF_TTL_RX) && - (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0)) - return "IP_RECVTTL"; - + return NULL; + } + -static void -sysio_process_rx_cmsgs(sock *s, struct msghdr *msg) ++static inline void ++sk_process_cmsg4_pktinfo(sock *s, struct cmsghdr *cm) + { - struct cmsghdr *cm; - struct in_pktinfo *pi = NULL; - int *ttl = NULL; - - for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm)) ++ if ((cm->cmsg_type == IP_PKTINFO) && (s->flags & SKF_LADDR_RX)) + { - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_PKTINFO) - pi = (struct in_pktinfo *) CMSG_DATA(cm); - - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_TTL) - ttl = (int *) CMSG_DATA(cm); ++ struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cm); ++ s->laddr = ipa_get_in4(&pi->ipi_addr); ++ s->lifindex = pi->ipi_ifindex; + } ++} + - if (s->flags & SKF_LADDR_RX) - { - if (pi) - { - get_inaddr(&s->laddr, &pi->ipi_addr); - s->lifindex = pi->ipi_ifindex; - } - else - { - s->laddr = IPA_NONE; - s->lifindex = 0; - } - } + - if (s->flags & SKF_TTL_RX) - s->ttl = ttl ? *ttl : -1; ++#define CMSG4_SPACE_TTL CMSG_SPACE(sizeof(int)) + +static inline char * - sk_request_pktinfo4(sock *s) ++sk_request_cmsg4_ttl(sock *s) +{ + int ok = 1; - if (s->flags & SKF_LADDR_RX) - if (setsockopt(s->fd, IPPROTO_IP, IP_PKTINFO, &ok, sizeof(ok)) < 0) - return "IP_PKTINFO"; ++ ++ if (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0) ++ return "IP_RECVTTL"; + + return NULL; +} - return; +static inline void - sk_process_rx_cmsg4(sock *s, struct cmsghdr *cm) ++sk_process_cmsg4_ttl(sock *s, struct cmsghdr *cm) +{ - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cm); - s->laddr = ipa_get_in4(&pi->ipi_addr); - s->lifindex = pi->ipi_ifindex; - } ++ if ((cm->cmsg_type == IP_TTL) && (s->flags & SKF_TTL_RX)) ++ s->ttl = * (int *) CMSG_DATA(cm); } ++ /* static void sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) diff --cc sysdep/unix/io.c index 93fe06e99,938638853..85b16b09a --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@@ -700,42 -685,65 +700,96 @@@ sk_insert(sock *s #ifndef IPV6_RECVPKTINFO #define IPV6_RECVPKTINFO IPV6_PKTINFO #endif + /* + * Same goes for IPV6_HOPLIMIT -> IPV6_RECVHOPLIMIT. + */ + #ifndef IPV6_RECVHOPLIMIT + #define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT + #endif + -static char * -sysio_register_cmsgs(sock *s) ++ ++#define CMSG6_SPACE_PKTINFO CMSG_SPACE(sizeof(struct in6_pktinfo)) + +static inline char * - sk_request_pktinfo6(sock *s) ++sk_request_cmsg6_pktinfo(sock *s) { int ok = 1; - if (s->flags & SKF_LADDR_RX) - if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ok, sizeof(ok)) < 0) - return "IPV6_RECVPKTINFO"; + - if ((s->flags & SKF_LADDR_RX) && - (setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ok, sizeof(ok)) < 0)) ++ if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ok, sizeof(ok)) < 0) + return "IPV6_RECVPKTINFO"; + - if ((s->flags & SKF_TTL_RX) && - (setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &ok, sizeof(ok)) < 0)) ++ return NULL; ++} ++ ++static inline void ++sk_process_cmsg6_pktinfo(sock *s, struct cmsghdr *cm) ++{ ++ if ((cm->cmsg_type == IPV6_PKTINFO) && (s->flags & SKF_LADDR_RX)) ++ { ++ struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cm); ++ s->laddr = ipa_get_in6(&pi->ipi6_addr); ++ s->lifindex = pi->ipi6_ifindex; ++ } ++} ++ ++ ++#define CMSG6_SPACE_TTL CMSG_SPACE(sizeof(int)) ++ ++static inline char * ++sk_request_cmsg6_ttl(sock *s) ++{ ++ int ok = 1; ++ ++ if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &ok, sizeof(ok)) < 0) + return "IPV6_RECVHOPLIMIT"; return NULL; } ++static inline void ++sk_process_cmsg6_ttl(sock *s, struct cmsghdr *cm) ++{ ++ if ((cm->cmsg_type == IPV6_HOPLIMIT) && (s->flags & SKF_TTL_RX)) ++ s->ttl = * (int *) CMSG_DATA(cm); ++} ++ ++ ++#define CMSG_RX_SPACE MAX(CMSG4_SPACE_PKTINFO+CMSG4_SPACE_TTL, \ ++ CMSG6_SPACE_PKTINFO+CMSG6_SPACE_TTL) ++#define CMSG_TX_SPACE MAX(CMSG4_SPACE_PKTINFO,CMSG6_SPACE_PKTINFO) ++ ++ static void - sk_process_rx_cmsgs(sock *s, struct msghdr *msg) -sysio_process_rx_cmsgs(sock *s, struct msghdr *msg) ++sk_process_cmsgs(sock *s, struct msghdr *msg) { struct cmsghdr *cm; - struct in6_pktinfo *pi = NULL; - int *hlim = NULL; - if (!(s->flags & SKF_LADDR_RX)) - return; - for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm)) ++ if (s->flags & SKF_LADDR_RX) + { - if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO) - pi = (struct in6_pktinfo *) CMSG_DATA(cm); - - if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_HOPLIMIT) - hlim = (int *) CMSG_DATA(cm); ++ s->laddr = IPA_NONE; ++ s->lifindex = 0; + } - s->laddr = IPA_NONE; - s->lifindex = 0; - if (s->flags & SKF_LADDR_RX) ++ if (s->flags & SKF_TTL_RX) ++ s->ttl = -1; + + for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm)) + { - if (pi) ++ if ((cm->cmsg_level == IPPROTO_IP) && sk_is_ipv4(s)) { - if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cm); - s->laddr = ipa_get_in6(&pi->ipi6_addr); - s->lifindex = pi->ipi6_ifindex; - } - get_inaddr(&s->laddr, &pi->ipi6_addr); - s->lifindex = pi->ipi6_ifindex; ++ sk_process_cmsg4_pktinfo(s, cm); ++ sk_process_cmsg4_ttl(s, cm); + } - else + - sk_process_rx_cmsg4(s, cm); ++ if ((cm->cmsg_level == IPPROTO_IPV6) && sk_is_ipv6(s)) + { - s->laddr = IPA_NONE; - s->lifindex = 0; ++ sk_process_cmsg6_pktinfo(s, cm); ++ sk_process_cmsg6_ttl(s, cm); } + } - - if (s->flags & SKF_TTL_RX) - s->ttl = hlim ? *hlim : -1; - - return; } ++ /* static void sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) @@@ -794,14 -815,16 +848,33 @@@ sk_setup(sock *s if (s->priority >= 0) sk_set_priority(s, s->priority); - // XXXX better error handling -#ifdef IPV6 - int v = 1; - if ((s->flags & SKF_V6ONLY) && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v)) < 0) - WARN("IPV6_V6ONLY"); -#endif - if (s->ttl >= 0) - sk_set_ttl(s, s->ttl); - err = sk_set_ttl_int(s); ++ if (sk_set_ttl(s, s->ttl) < 0) ++ ERR("sk_set_ttl"); + + if (sk_is_ipv4(s)) - err = sk_request_pktinfo4(s); - else - err = sk_request_pktinfo6(s); ++ { ++ if (s->flags & SKF_LADDR_RX) ++ if (err = sk_request_cmsg4_pktinfo(s)) ++ goto bad; ++ ++ if (s->flags & SKF_TTL_RX) ++ if (err = sk_request_cmsg4_ttl(s)) ++ goto bad; ++ } ++ ++ if (sk_is_ipv6(s)) ++ { ++ if (s->flags & SKF_LADDR_RX) ++ if (err = sk_request_cmsg6_pktinfo(s)) ++ goto bad; ++ ++ if (s->flags & SKF_TTL_RX) ++ if (err = sk_request_cmsg6_ttl(s)); ++ } ++ ++ return NULL; + - sysio_register_cmsgs(s); bad: return err; } @@@ -1492,8 -1487,8 +1565,8 @@@ sk_read(sock *s return 0; } s->rpos = s->rbuf + e; - get_sockaddr(&sa, &s->faddr, NULL, &s->fport, 1); - sysio_process_rx_cmsgs(s, &msg); + sockaddr_read(sa, &s->faddr, NULL, &s->fport, 1); - sk_process_rx_cmsgs(s, &msg); ++ sk_process_cmsgs(s, &msg); s->rx_hook(s, e); return 1;