0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-03-11 17:08:46 +00:00

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
This commit is contained in:
Ondrej Zajicek 2013-07-31 16:16:48 +02:00
commit 6abc22f4b0
12 changed files with 249 additions and 78 deletions

View File

@ -470,7 +470,7 @@ to zero to disable it. An empty <cf><m/switch/</cf> is equivalent to <cf/on/
works in the direction from the routing table to the protocol.
Default: <cf/none/.
<tag>import keep filtered <m/bool/</tag>
<tag>import keep filtered <m/switch/</tag>
Usually, if an import filter rejects a route, the route is
forgotten. When this option is active, these routes are
kept in the routing table, but they are hidden and not
@ -1966,6 +1966,9 @@ protocol ospf &lt;name&gt; {
ptp netmask &lt;switch&gt;;
check link &lt;switch&gt;;
ecmp weight &lt;num&gt;;
ttl security [&lt;switch&gt;; | tx only]
tx class|dscp &lt;num&gt;;
tx priority &lt;num&gt;;
authentication [none|simple|cryptographic];
password "&lt;text&gt;";
password "&lt;text&gt;" {
@ -2236,6 +2239,20 @@ protocol ospf &lt;name&gt; {
prefix) is propagated. It is possible that some hardware
drivers or platforms do not implement this feature. Default value is no.
<tag>ttl security [<m/switch/ | tx only]</tag>
TTL security is a feature that protects routing protocols
from remote spoofed packets by using TTL 255 instead of TTL 1
for protocol packets destined to neighbors. Because TTL is
decremented when packets are forwarded, it is non-trivial to
spoof packets with TTL 255 from remote locations. Note that
this option would interfere with OSPF virtual links.
If this option is enabled, the router will send OSPF packets
with TTL 255 and drop received packets with TTL less than
255. If this option si set to <cf/tx only/, TTL 255 is used
for sent packets, but is not checked for received
packets. Default value is no.
<tag>tx class|dscp|priority <m/num/</tag>
These options specify the ToS/DiffServ/Traffic class/Priority
of the outgoing OSPF packets. See <ref id="dsc-prio" name="tx
@ -2784,6 +2801,26 @@ makes it pretty much obsolete. (It is still usable on very small networks.)
any periodic messages to this interface and <cf/nolisten/
means that RIP will send to this interface butnot listen to it.
<tag>ttl security [<m/switch/ | tx only]</tag>
TTL security is a feature that protects routing protocols
from remote spoofed packets by using TTL 255 instead of TTL 1
for protocol packets destined to neighbors. Because TTL is
decremented when packets are forwarded, it is non-trivial to
spoof packets with TTL 255 from remote locations.
If this option is enabled, the router will send RIP packets
with TTL 255 and drop received packets with TTL less than
255. If this option si set to <cf/tx only/, TTL 255 is used
for sent packets, but is not checked for received
packets. Such setting does not offer protection, but offers
compatibility with neighbors regardless of whether they use
ttl security.
Note that for RIPng, TTL security is a standard behavior
(required by RFC 2080), but BIRD uses <cf/tx only/ by
default, for compatibility with older versions. For IPv4 RIP,
default value is no.
<tag>tx class|dscp|priority <m/num/</tag>
These options specify the ToS/DiffServ/Traffic class/Priority
of the outgoing RIP packets. See <ref id="dsc-prio" name="tx

View File

@ -89,10 +89,11 @@ extern int sk_priority_control; /* Suggested priority for control traffic, shoul
/* 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_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 */
/*

View File

@ -112,8 +112,8 @@ CF_KEYWORDS(OSPF, OSPF2, OSPF3, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, COST2, RETRANSMIT)
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, TYPE, BROADCAST, BCAST)
CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC, TTL, SECURITY)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK, ONLY)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK, TX, PRIORITY)
@ -297,6 +297,8 @@ 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 { ospf_check_auth(); }
;

View File

@ -88,7 +88,7 @@ ospf_sk_open(struct ospf_iface *ifa)
sk->rbsize = rxbufsize(ifa);
sk->tbsize = rxbufsize(ifa);
sk->data = (void *) ifa;
sk->flags = SKF_LADDR_RX;
sk->flags = SKF_LADDR_RX | (ifa->check_ttl ? SKF_TTL_RX : 0);
if (sk_open(sk) != 0)
goto err;
@ -134,7 +134,7 @@ ospf_sk_open(struct ospf_iface *ifa)
{
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,6 +535,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
ifa->rxbuf = ip->rxbuf;
ifa->check_link = ip->check_link;
ifa->ecmp_weight = ip->ecmp_weight;
ifa->check_ttl = (ip->ttl_security == 1);
ifa->autype = ip->autype;
ifa->passwords = ip->passwords;
ifa->instance_id = ip->instance_id;

View File

@ -248,6 +248,7 @@ struct ospf_iface
u8 check_link; /* Whether iface link change is used */
u8 ecmp_weight; /* Weight used for ECMP */
u8 ptp_netmask; /* Send real netmask for P2P */
u8 check_ttl; /* Check incoming packets for TTL 255 */
};
struct ospf_md5
@ -754,7 +755,8 @@ struct ospf_iface_patt
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 */
u8 instance_id;
list *passwords;
};

View File

@ -311,6 +311,12 @@ ospf_rx_hook(sock *sk, int size)
return 1;
}
if (ifa->check_ttl && (sk->ttl < 255))
{
log(L_ERR "%s%I - TTL %d (< 255)", mesg, sk->faddr, sk->ttl);
return 1;
}
if ((unsigned) size < sizeof(struct ospf_packet))
{
log(L_ERR "%s%I - too short (%u bytes)", mesg, sk->faddr, size);

View File

@ -22,12 +22,15 @@ CF_DEFINES
#define RIP_CFG ((struct rip_proto_config *) this_proto)
#define RIP_IPATT ((struct rip_patt *) this_ipatt)
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, 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 <i> rip_mode rip_auth
@ -87,6 +90,8 @@ rip_iface_item:
| MODE rip_mode { RIP_IPATT->mode |= $2; }
| TX tos { RIP_IPATT->tx_tos = $2; }
| TX PRIORITY expr { RIP_IPATT->tx_priority = $3; }
| TTL SECURITY bool { RIP_IPATT->ttl_security = $3; }
| TTL SECURITY TX ONLY { RIP_IPATT->ttl_security = 2; }
;
rip_iface_opts:
@ -107,6 +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_cfg_is_ng() ? 1 : 0;
}
;

View File

@ -481,6 +481,14 @@ rip_rx(sock *s, int size)
iface = i->iface;
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, iface ? iface->name : "(dummy)" );
size -= sizeof( struct rip_packet_heading );
@ -687,6 +695,7 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
rif->mode = PATT->mode;
rif->metric = PATT->metric;
rif->multicast = (!(PATT->mode & IM_BROADCAST)) && (flags & IF_MULTICAST);
rif->check_ttl = (PATT->ttl_security == 1);
}
/* lookup multicasts over unnumbered links - no: rip is not defined over unnumbered links */
@ -708,10 +717,10 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
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);
}
if (new) {

View File

@ -109,6 +109,7 @@ struct rip_interface {
struct rip_connection *busy;
int metric; /* You don't want to put struct rip_patt *patt here -- think about reconfigure */
int mode;
int check_ttl; /* Check incoming packets for TTL 255 */
int triggered;
struct object_lock *lock;
int multicast;
@ -125,6 +126,7 @@ struct rip_patt {
#define IM_VERSION1 16
int tx_tos;
int tx_priority;
int ttl_security; /* bool + 2 for TX only (send, but do not check on RX) */
};
struct rip_proto_config {

View File

@ -81,43 +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_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)
#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_RECVIF, &ok, sizeof(ok)) < 0)
return "IP_RECVIF";
}
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)
static inline void
sk_process_cmsg4_pktinfo(sock *s, struct cmsghdr *cm)
{
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_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)
{
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);
if ((cm->cmsg_type == IP_RECVIF) && (s->flags & SKF_LADDR_RX))
s->lifindex = ((struct sockaddr_dl *) CMSG_DATA(cm))->sdl_index;
}
static inline char *
sk_request_cmsg4_ttl(sock *s)
{
int ok = 1;
if (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0)
return "IP_RECVTTL";
return NULL;
}
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

View File

@ -157,34 +157,52 @@ sk_set_md5_auth_int(sock *s, struct sockaddr *sa, int sa_len, char *passwd)
/* 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 MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6)
#define CMSG_TX_SPACE MAX(CMSG_SPACE_PKTINFO4,CMSG_SPACE_PKTINFO6)
#define CMSG4_SPACE_PKTINFO CMSG_SPACE(sizeof(struct in_pktinfo))
static inline char *
sk_request_pktinfo4(sock *s)
sk_request_cmsg4_pktinfo(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_PKTINFO, &ok, sizeof(ok)) < 0)
return "IP_PKTINFO";
return NULL;
}
static inline void
sk_process_rx_cmsg4(sock *s, struct cmsghdr *cm)
sk_process_cmsg4_pktinfo(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_PKTINFO) && (s->flags & SKF_LADDR_RX))
{
struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cm);
s->laddr = ipa_get_in4(&pi->ipi_addr);
s->lifindex = pi->ipi_ifindex;
}
}
#define CMSG4_SPACE_TTL CMSG_SPACE(sizeof(int))
static inline char *
sk_request_cmsg4_ttl(sock *s)
{
int ok = 1;
if (setsockopt(s->fd, IPPROTO_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0)
return "IP_RECVTTL";
return NULL;
}
static inline void
sk_process_cmsg4_ttl(sock *s, struct cmsghdr *cm)
{
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)

View File

@ -700,42 +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
#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 (setsockopt(s->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &ok, sizeof(ok)) < 0)
return "IPV6_RECVPKTINFO";
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)
sk_process_cmsgs(sock *s, struct msghdr *msg)
{
struct cmsghdr *cm;
if (!(s->flags & SKF_LADDR_RX))
return;
if (s->flags & SKF_LADDR_RX)
{
s->laddr = IPA_NONE;
s->lifindex = 0;
}
s->laddr = IPA_NONE;
s->lifindex = 0;
if (s->flags & SKF_TTL_RX)
s->ttl = -1;
for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm))
{
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;
}
sk_process_rx_cmsg4(s, cm);
sk_process_cmsg4_pktinfo(s, cm);
sk_process_cmsg4_ttl(s, cm);
}
if ((cm->cmsg_level == IPPROTO_IPV6) && sk_is_ipv6(s))
{
sk_process_cmsg6_pktinfo(s, cm);
sk_process_cmsg6_ttl(s, cm);
}
}
}
/*
static void
sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
@ -794,14 +848,33 @@ sk_setup(sock *s)
if (s->priority >= 0)
sk_set_priority(s, s->priority);
// XXXX better error handling
if (s->ttl >= 0)
sk_set_ttl(s, s->ttl);
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;
bad:
return err;
}
@ -1493,7 +1566,7 @@ sk_read(sock *s)
}
s->rpos = s->rbuf + e;
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;