]>
git.proxmox.com Git - mirror_frr.git/blob - nhrpd/linux.c
1 /* NHRP daemon Linux specific glue
2 * Copyright (c) 2014-2015 Timo Teräs
4 * This file is free software: you may copy, redistribute and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
18 #include <sys/ioctl.h>
19 #include <sys/socket.h>
20 #include <sys/types.h>
21 #include <asm/types.h>
22 #include <arpa/inet.h>
23 #include <linux/netlink.h>
24 #include <linux/rtnetlink.h>
26 #include <linux/if_arp.h>
27 #include <linux/if_tunnel.h>
29 #include "nhrp_protocol.h"
33 static int nhrp_socket_fd
= -1;
37 if (nhrp_socket_fd
< 0)
39 socket(PF_PACKET
, SOCK_DGRAM
, htons(ETH_P_NHRP
));
40 return nhrp_socket_fd
;
43 int os_sendmsg(const uint8_t *buf
, size_t len
, int ifindex
, const uint8_t *addr
,
46 struct sockaddr_ll lladdr
;
48 .iov_base
= (void *)buf
, .iov_len
= len
,
52 .msg_namelen
= sizeof(lladdr
),
58 if (addrlen
> sizeof(lladdr
.sll_addr
))
61 memset(&lladdr
, 0, sizeof(lladdr
));
62 lladdr
.sll_family
= AF_PACKET
;
63 lladdr
.sll_protocol
= htons(ETH_P_NHRP
);
64 lladdr
.sll_ifindex
= ifindex
;
65 lladdr
.sll_halen
= addrlen
;
66 memcpy(lladdr
.sll_addr
, addr
, addrlen
);
68 status
= sendmsg(nhrp_socket_fd
, &msg
, 0);
75 int os_recvmsg(uint8_t *buf
, size_t *len
, int *ifindex
, uint8_t *addr
,
78 struct sockaddr_ll lladdr
;
80 .iov_base
= buf
, .iov_len
= *len
,
84 .msg_namelen
= sizeof(lladdr
),
90 r
= recvmsg(nhrp_socket_fd
, &msg
, MSG_DONTWAIT
);
95 *ifindex
= lladdr
.sll_ifindex
;
97 if (*addrlen
<= (size_t)lladdr
.sll_addr
) {
98 if (memcmp(lladdr
.sll_addr
, "\x00\x00\x00\x00", 4) != 0) {
99 memcpy(addr
, lladdr
.sll_addr
, lladdr
.sll_halen
);
100 *addrlen
= lladdr
.sll_halen
;
109 static int linux_configure_arp(const char *iface
, int on
)
113 strncpy(ifr
.ifr_name
, iface
, IFNAMSIZ
- 1);
114 if (ioctl(nhrp_socket_fd
, SIOCGIFFLAGS
, &ifr
))
118 ifr
.ifr_flags
&= ~IFF_NOARP
;
120 ifr
.ifr_flags
|= IFF_NOARP
;
122 if (ioctl(nhrp_socket_fd
, SIOCSIFFLAGS
, &ifr
))
128 static int linux_icmp_redirect_off(const char *iface
)
133 sprintf(fname
, "/proc/sys/net/ipv4/conf/%s/send_redirects", iface
);
134 fd
= open(fname
, O_WRONLY
);
137 if (write(fd
, "0\n", 2) == 2)
144 int os_configure_dmvpn(unsigned int ifindex
, const char *ifname
, int af
)
150 ret
|= linux_icmp_redirect_off("all");
151 ret
|= linux_icmp_redirect_off(ifname
);
154 ret
|= linux_configure_arp(ifname
, 1);
155 ret
|= netlink_configure_arp(ifindex
, af
);