diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2014-02-06 17:46:01 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2014-02-06 17:46:01 +0100 |
commit | 48e5f32db676645640f84ab3d630cce975aa6b20 (patch) | |
tree | b940fc8156b3e0c18aab6c339a066bdb7a9ec1e0 /sysdep/linux/sysio.h | |
parent | f48fa14214301382b2e6b134788a7506b61b664f (diff) |
Many changes in I/O and OSPF sockets and packet handling.
I/O:
- BSD: specify src addr on IP sockets by IP_HDRINCL
- BSD: specify src addr on UDP sockets by IP_SENDSRCADDR
- Linux: specify src addr on IP/UDP sockets by IP_PKTINFO
- IPv6: specify src addr on IP/UDP sockets by IPV6_PKTINFO
- Alternative SKF_BIND flag for binding to IP address
- Allows IP/UDP sockets without tx_hook, on these
sockets a packet is discarded when TX queue is full
- Use consistently SOL_ for socket layer values.
OSPF:
- Packet src addr is always explicitly set
- Support for secondary addresses in BSD
- Dynamic RX/TX buffers
- Fixes some minor buffer overruns
- Interface option 'tx length'
- Names for vlink pseudoifaces (vlinkX)
- Vlinks use separate socket for TX
- Vlinks do not use fixed associated iface
- Fixes TTL for direct unicast packets
- Fixes DONTROUTE for OSPF sockets
- Use ifa->ifname instead of ifa->iface->name
Diffstat (limited to 'sysdep/linux/sysio.h')
-rw-r--r-- | sysdep/linux/sysio.h | 56 |
1 files changed, 16 insertions, 40 deletions
diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index 250ed586..56c3387d 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -30,17 +30,6 @@ get_inaddr(ip_addr *a, struct in6_addr *ia) ipa_ntoh(*a); } -static inline char * -sysio_bind_to_iface(sock *s) -{ - struct ifreq ifr; - strcpy(ifr.ifr_name, s->iface->name); - if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) - return "SO_BINDTODEVICE"; - - return NULL; -} - #else static inline void @@ -69,11 +58,10 @@ struct ip_mreqn #endif -static inline void fill_mreqn(struct ip_mreqn *m, struct iface *ifa, ip_addr saddr, ip_addr maddr) +static inline void fill_mreqn(struct ip_mreqn *m, ip_addr maddr, struct iface *ifa) { bzero(m, sizeof(*m)); m->imr_ifindex = ifa->index; - set_inaddr(&m->imr_address, saddr); set_inaddr(&m->imr_multiaddr, maddr); } @@ -90,16 +78,10 @@ sysio_setup_multicast(sock *s) return "IP_MULTICAST_TTL"; /* This defines where should we send _outgoing_ multicasts */ - fill_mreqn(&m, s->iface, s->saddr, IPA_NONE); + fill_mreqn(&m, IPA_NONE, s->iface); if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_IF, &m, sizeof(m)) < 0) return "IP_MULTICAST_IF"; - /* Is this necessary? */ - struct ifreq ifr; - strcpy(ifr.ifr_name, s->iface->name); - if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) - return "SO_BINDTODEVICE"; - return NULL; } @@ -109,7 +91,7 @@ sysio_join_group(sock *s, ip_addr maddr) struct ip_mreqn m; /* And this one sets interface for _receiving_ multicasts from */ - fill_mreqn(&m, s->iface, s->saddr, maddr); + fill_mreqn(&m, maddr, s->iface); if (setsockopt(s->fd, SOL_IP, IP_ADD_MEMBERSHIP, &m, sizeof(m)) < 0) return "IP_ADD_MEMBERSHIP"; @@ -122,7 +104,7 @@ sysio_leave_group(sock *s, ip_addr maddr) struct ip_mreqn m; /* And this one sets interface for _receiving_ multicasts from */ - fill_mreqn(&m, s->iface, s->saddr, maddr); + fill_mreqn(&m, maddr, s->iface); if (setsockopt(s->fd, SOL_IP, IP_DROP_MEMBERSHIP, &m, sizeof(m)) < 0) return "IP_DROP_MEMBERSHIP"; @@ -132,10 +114,7 @@ sysio_leave_group(sock *s, ip_addr maddr) #endif -#include <linux/socket.h> -#include <linux/tcp.h> - -/* For the case that we have older kernel headers */ +/* For the case that we have older libc headers */ /* Copied from Linux kernel file include/linux/tcp.h */ #ifndef TCP_MD5SIG @@ -175,7 +154,7 @@ sk_set_md5_auth_int(sock *s, sockaddr *sa, char *passwd) memcpy(&md5.tcpm_key, passwd, len); } - int rv = setsockopt(s->fd, IPPROTO_TCP, TCP_MD5SIG, &md5, sizeof(md5)); + int rv = setsockopt(s->fd, SOL_TCP, TCP_MD5SIG, &md5, sizeof(md5)); if (rv < 0) { @@ -203,11 +182,11 @@ sysio_register_cmsgs(sock *s) int ok = 1; if ((s->flags & SKF_LADDR_RX) && - (setsockopt(s->fd, IPPROTO_IP, IP_PKTINFO, &ok, sizeof(ok)) < 0)) + (setsockopt(s->fd, SOL_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)) + (setsockopt(s->fd, SOL_IP, IP_RECVTTL, &ok, sizeof(ok)) < 0)) return "IP_RECVTTL"; return NULL; @@ -222,10 +201,10 @@ sysio_process_rx_cmsgs(sock *s, struct msghdr *msg) for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm)) { - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_PKTINFO) + if (cm->cmsg_level == SOL_IP && cm->cmsg_type == IP_PKTINFO) pi = (struct in_pktinfo *) CMSG_DATA(cm); - if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_TTL) + if (cm->cmsg_level == SOL_IP && cm->cmsg_type == IP_TTL) ttl = (int *) CMSG_DATA(cm); } @@ -249,31 +228,28 @@ sysio_process_rx_cmsgs(sock *s, struct msghdr *msg) return; } -/* static void sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) { struct cmsghdr *cm; struct in_pktinfo *pi; - if (!(s->flags & SKF_LADDR_TX)) - return; - msg->msg_control = cbuf; msg->msg_controllen = cbuflen; cm = CMSG_FIRSTHDR(msg); - cm->cmsg_level = IPPROTO_IP; + cm->cmsg_level = SOL_IP; cm->cmsg_type = IP_PKTINFO; cm->cmsg_len = CMSG_LEN(sizeof(*pi)); pi = (struct in_pktinfo *) CMSG_DATA(cm); - set_inaddr(&pi->ipi_spec_dst, s->saddr); pi->ipi_ifindex = s->iface ? s->iface->index : 0; + set_inaddr(&pi->ipi_spec_dst, s->saddr); + set_inaddr(&pi->ipi_addr, IPA_NONE); msg->msg_controllen = cm->cmsg_len; } -*/ + #endif @@ -292,7 +268,7 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) static int sk_set_min_ttl4(sock *s, int ttl) { - if (setsockopt(s->fd, IPPROTO_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0) + if (setsockopt(s->fd, SOL_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0) { if (errno == ENOPROTOOPT) log(L_ERR "Kernel does not support IPv4 TTL security"); @@ -310,7 +286,7 @@ sk_set_min_ttl4(sock *s, int ttl) static int sk_set_min_ttl6(sock *s, int ttl) { - if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_MINHOPCOUNT, &ttl, sizeof(ttl)) < 0) + if (setsockopt(s->fd, SOL_IPV6, IPV6_MINHOPCOUNT, &ttl, sizeof(ttl)) < 0) { if (errno == ENOPROTOOPT) log(L_ERR "Kernel does not support IPv6 TTL security"); |