Rename netlink infrastructure to rtnetlink
We will introduce genetlink infrastructure just after this.
This commit is contained in:
parent
fdf19f5467
commit
60329986b2
3 changed files with 102 additions and 65 deletions
161
l2tpns.c
161
l2tpns.c
|
|
@ -63,7 +63,7 @@ uint32_t call_serial_number = 0;
|
|||
|
||||
// Globals
|
||||
configt *config = NULL; // all configuration
|
||||
int nlfd = -1; // netlink socket
|
||||
int rtnlfd = -1; // route netlink socket
|
||||
int tunfd = -1; // tun interface file handle. (network device)
|
||||
int udpfd[MAX_UDPFD + 1] = INIT_TABUDPFD; // array UDP file handle + 1 for lac udp
|
||||
int udplacfd = -1; // UDP LAC file handle
|
||||
|
|
@ -78,8 +78,8 @@ int epollfd = -1; // event polling
|
|||
time_t basetime = 0; // base clock
|
||||
char hostname[MAXHOSTNAME] = ""; // us.
|
||||
static int tunidx; // ifr_ifindex of tun device
|
||||
int nlseqnum = 0; // netlink sequence number
|
||||
int min_initok_nlseqnum = 0; // minimun seq number for messages after init is ok
|
||||
int rtnlseqnum = 0; // route netlink sequence number
|
||||
int min_initok_rtnlseqnum = 0; // minimun seq number for messages after init is ok
|
||||
static int syslog_log = 0; // are we logging to syslog
|
||||
FILE *log_stream = 0; // file handle for direct logging (i.e. direct into file, not via syslog).
|
||||
uint32_t last_id = 0; // Unique ID for radius accounting
|
||||
|
|
@ -240,8 +240,9 @@ struct Tstats *_statistics = NULL;
|
|||
struct Tringbuffer *ringbuffer = NULL;
|
||||
#endif
|
||||
|
||||
static ssize_t netlink_send(struct nlmsghdr *nh);
|
||||
static void netlink_addattr(struct nlmsghdr *nh, int type, const void *data, int alen);
|
||||
static ssize_t rtnetlink_send(struct nlmsghdr *nh);
|
||||
static int netlink_handle_ack(struct nlmsghdr *nh, int min_initok_nlseqnum, char *tun_nl_phase_msg[]);
|
||||
static void rtnetlink_addattr(struct nlmsghdr *nh, int type, const void *data, int alen);
|
||||
static void cache_ipmap(in_addr_t ip, sessionidt s);
|
||||
static void uncache_ipmap(in_addr_t ip);
|
||||
static void cache_ipv6map(struct in6_addr ip, int prefixlen, sessionidt s);
|
||||
|
|
@ -497,20 +498,20 @@ static void routeset(sessionidt s, in_addr_t ip, int prefixlen, in_addr_t gw, in
|
|||
req.rt.rtm_scope = RT_SCOPE_LINK;
|
||||
req.rt.rtm_type = RTN_UNICAST;
|
||||
|
||||
netlink_addattr(&req.nh, RTA_OIF, &tunidx, sizeof(int));
|
||||
rtnetlink_addattr(&req.nh, RTA_OIF, &tunidx, sizeof(int));
|
||||
n_ip = htonl(ip);
|
||||
netlink_addattr(&req.nh, RTA_DST, &n_ip, sizeof(n_ip));
|
||||
rtnetlink_addattr(&req.nh, RTA_DST, &n_ip, sizeof(n_ip));
|
||||
if (gw)
|
||||
{
|
||||
n_ip = htonl(gw);
|
||||
netlink_addattr(&req.nh, RTA_GATEWAY, &n_ip, sizeof(n_ip));
|
||||
rtnetlink_addattr(&req.nh, RTA_GATEWAY, &n_ip, sizeof(n_ip));
|
||||
}
|
||||
|
||||
LOG(1, s, session[s].tunnel, "Route %s %s/%d%s%s\n", add ? "add" : "del",
|
||||
fmtaddr(htonl(ip), 0), prefixlen,
|
||||
gw ? " via" : "", gw ? fmtaddr(htonl(gw), 2) : "");
|
||||
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
LOG(0, 0, 0, "routeset() error in sending netlink message: %s\n", strerror(errno));
|
||||
|
||||
#ifdef BGP
|
||||
|
|
@ -576,17 +577,17 @@ void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add)
|
|||
req.rt.rtm_scope = RT_SCOPE_LINK;
|
||||
req.rt.rtm_type = RTN_UNICAST;
|
||||
|
||||
netlink_addattr(&req.nh, RTA_OIF, &tunidx, sizeof(int));
|
||||
netlink_addattr(&req.nh, RTA_DST, &ip, sizeof(ip));
|
||||
rtnetlink_addattr(&req.nh, RTA_OIF, &tunidx, sizeof(int));
|
||||
rtnetlink_addattr(&req.nh, RTA_DST, &ip, sizeof(ip));
|
||||
metric = 1;
|
||||
netlink_addattr(&req.nh, RTA_METRICS, &metric, sizeof(metric));
|
||||
rtnetlink_addattr(&req.nh, RTA_METRICS, &metric, sizeof(metric));
|
||||
|
||||
LOG(1, s, session[s].tunnel, "Route %s %s/%d\n",
|
||||
add ? "add" : "del",
|
||||
inet_ntop(AF_INET6, &ip, ipv6addr, INET6_ADDRSTRLEN),
|
||||
prefixlen);
|
||||
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
LOG(0, 0, 0, "route6set() error in sending netlink message: %s\n", strerror(errno));
|
||||
|
||||
#ifdef BGP
|
||||
|
|
@ -613,10 +614,10 @@ static void initnetlink(void)
|
|||
{
|
||||
struct sockaddr_nl nladdr;
|
||||
|
||||
nlfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (nlfd < 0)
|
||||
rtnlfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (rtnlfd < 0)
|
||||
{
|
||||
LOG(0, 0, 0, "Can't create netlink socket: %s\n", strerror(errno));
|
||||
LOG(0, 0, 0, "Can't create route netlink socket: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -624,21 +625,23 @@ static void initnetlink(void)
|
|||
nladdr.nl_family = AF_NETLINK;
|
||||
nladdr.nl_pid = getpid();
|
||||
|
||||
if (bind(nlfd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0)
|
||||
if (bind(rtnlfd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0)
|
||||
{
|
||||
LOG(0, 0, 0, "Can't bind netlink socket: %s\n", strerror(errno));
|
||||
LOG(0, 0, 0, "Can't bind route netlink socket: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t netlink_send(struct nlmsghdr *nh)
|
||||
//
|
||||
// Send message to a netlink socket
|
||||
static ssize_t netlink_send(int fd, int *seqnum, struct nlmsghdr *nh)
|
||||
{
|
||||
struct sockaddr_nl nladdr;
|
||||
struct iovec iov;
|
||||
struct msghdr msg;
|
||||
|
||||
nh->nlmsg_pid = getpid();
|
||||
nh->nlmsg_seq = ++nlseqnum;
|
||||
nh->nlmsg_seq = ++*seqnum;
|
||||
|
||||
// set kernel address
|
||||
memset(&nladdr, 0, sizeof(nladdr));
|
||||
|
|
@ -647,10 +650,19 @@ static ssize_t netlink_send(struct nlmsghdr *nh)
|
|||
iov = (struct iovec){ (void *)nh, nh->nlmsg_len };
|
||||
msg = (struct msghdr){ (void *)&nladdr, sizeof(nladdr), &iov, 1, NULL, 0, 0 };
|
||||
|
||||
return sendmsg(nlfd, &msg, 0);
|
||||
return sendmsg(fd, &msg, 0);
|
||||
}
|
||||
|
||||
static ssize_t netlink_recv(void *buf, ssize_t len)
|
||||
//
|
||||
// Send message to the route netlink socket
|
||||
static ssize_t rtnetlink_send(struct nlmsghdr *nh)
|
||||
{
|
||||
return netlink_send(rtnlfd, &rtnlseqnum, nh);
|
||||
}
|
||||
|
||||
//
|
||||
// Receive a message from a netlink socket
|
||||
static ssize_t netlink_recv(int fd, void *buf, ssize_t len)
|
||||
{
|
||||
struct sockaddr_nl nladdr;
|
||||
struct iovec iov;
|
||||
|
|
@ -663,11 +675,52 @@ static ssize_t netlink_recv(void *buf, ssize_t len)
|
|||
iov = (struct iovec){ buf, len };
|
||||
msg = (struct msghdr){ (void *)&nladdr, sizeof(nladdr), &iov, 1, NULL, 0, 0 };
|
||||
|
||||
return recvmsg(nlfd, &msg, 0);
|
||||
return recvmsg(fd, &msg, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Receive a message from the route netlink socket
|
||||
static ssize_t rtnetlink_recv(void *buf, ssize_t len)
|
||||
{
|
||||
return netlink_recv(rtnlfd, buf, len);
|
||||
}
|
||||
|
||||
//
|
||||
// Look ack netlink message for errors
|
||||
static int netlink_handle_ack(struct nlmsghdr *nh, int min_initok_nlseqnum, char *tun_nl_phase_msg[])
|
||||
{
|
||||
if (nh->nlmsg_type == NLMSG_ERROR)
|
||||
{
|
||||
struct nlmsgerr *errmsg = NLMSG_DATA(nh);
|
||||
if (errmsg->error)
|
||||
{
|
||||
if (errmsg->msg.nlmsg_seq < min_initok_nlseqnum)
|
||||
{
|
||||
LOG(0, 0, 0, "Got a fatal netlink error (while %s): %s\n", tun_nl_phase_msg[nh->nlmsg_seq], strerror(-errmsg->error));
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(0, 0, 0, "For netlink request %d, got a netlink error: %s\n", errmsg->msg.nlmsg_type, strerror(-errmsg->error));
|
||||
errno = -errmsg->error;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// else it's an ack
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(1, 0, 0, "Got an unknown netlink message: type %d seq %d flags %d\n", nh->nlmsg_type, nh->nlmsg_seq, nh->nlmsg_flags);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add an attribute to a message for a route netlink socket
|
||||
/* adapted from iproute2 */
|
||||
static void netlink_addattr(struct nlmsghdr *nh, int type, const void *data, int alen)
|
||||
static void rtnetlink_addattr(struct nlmsghdr *nh, int type, const void *data, int alen)
|
||||
{
|
||||
int len = RTA_LENGTH(alen);
|
||||
struct rtattr *rta;
|
||||
|
|
@ -680,7 +733,7 @@ static void netlink_addattr(struct nlmsghdr *nh, int type, const void *data, int
|
|||
}
|
||||
|
||||
// messages corresponding to different phases seq number
|
||||
static char *tun_nl_phase_msg[] = {
|
||||
static char *tun_rtnl_phase_msg[] = {
|
||||
"initialized",
|
||||
"getting tun interface index",
|
||||
"setting tun interface parameters",
|
||||
|
|
@ -753,12 +806,12 @@ static void inittun(void)
|
|||
|
||||
/* Bump up the qlen to deal with bursts from the network */
|
||||
txqlen = 1000;
|
||||
netlink_addattr(&req.nh, IFLA_TXQLEN, &txqlen, sizeof(txqlen));
|
||||
rtnetlink_addattr(&req.nh, IFLA_TXQLEN, &txqlen, sizeof(txqlen));
|
||||
/* set MTU to modem MRU */
|
||||
mtu = MRU;
|
||||
netlink_addattr(&req.nh, IFLA_MTU, &mtu, sizeof(mtu));
|
||||
rtnetlink_addattr(&req.nh, IFLA_MTU, &mtu, sizeof(mtu));
|
||||
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
goto senderror;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
|
@ -778,8 +831,8 @@ static void inittun(void)
|
|||
for (i = 0; i < config->nbmultiaddress ; i++)
|
||||
{
|
||||
ip = config->iftun_n_address[i];
|
||||
netlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
rtnetlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
goto senderror;
|
||||
}
|
||||
}
|
||||
|
|
@ -789,9 +842,9 @@ static void inittun(void)
|
|||
ip = config->iftun_address;
|
||||
else
|
||||
ip = 0x01010101; // 1.1.1.1
|
||||
netlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
|
||||
rtnetlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
|
||||
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
goto senderror;
|
||||
}
|
||||
|
||||
|
|
@ -817,9 +870,9 @@ static void inittun(void)
|
|||
ip6.s6_addr[0] = 0xFE;
|
||||
ip6.s6_addr[1] = 0x80;
|
||||
ip6.s6_addr[15] = 1;
|
||||
netlink_addattr(&req.nh, IFA_LOCAL, &ip6, sizeof(ip6));
|
||||
rtnetlink_addattr(&req.nh, IFA_LOCAL, &ip6, sizeof(ip6));
|
||||
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
goto senderror;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
|
@ -836,9 +889,9 @@ static void inittun(void)
|
|||
// Global address is prefix::1
|
||||
ip6 = config->ipv6_prefix;
|
||||
ip6.s6_addr[15] = 1;
|
||||
netlink_addattr(&req.nh, IFA_LOCAL, &ip6, sizeof(ip6));
|
||||
rtnetlink_addattr(&req.nh, IFA_LOCAL, &ip6, sizeof(ip6));
|
||||
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
goto senderror;
|
||||
}
|
||||
|
||||
|
|
@ -847,15 +900,15 @@ static void inittun(void)
|
|||
req.nh.nlmsg_type = NLMSG_DONE;
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(0);
|
||||
|
||||
if (netlink_send(&req.nh) < 0)
|
||||
if (rtnetlink_send(&req.nh) < 0)
|
||||
goto senderror;
|
||||
|
||||
// if we get an error for seqnum < min_initok_nlseqnum,
|
||||
// we must exit as initialization went wrong
|
||||
if (config->ipv6_prefix.s6_addr[0])
|
||||
min_initok_nlseqnum = 5 + 1; // idx + if + addr + 2*addr6
|
||||
min_initok_rtnlseqnum = 5 + 1; // idx + if + addr + 2*addr6
|
||||
else
|
||||
min_initok_nlseqnum = 3 + 1; // idx + if + addr
|
||||
min_initok_rtnlseqnum = 3 + 1; // idx + if + addr
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -4135,8 +4188,8 @@ static void mainloop(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d , udplacfd=%d, pppoefd=%d, pppoesessfd=%d\n",
|
||||
clifd, cluster_sockfd, tunfd, udpfd[0], controlfd, daefd, nlfd, udplacfd, pppoediscfd, pppoesessfd);
|
||||
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, rtnlfd=%d , udplacfd=%d, pppoefd=%d, pppoesessfd=%d\n",
|
||||
clifd, cluster_sockfd, tunfd, udpfd[0], controlfd, daefd, rtnlfd, udplacfd, pppoediscfd, pppoesessfd);
|
||||
|
||||
/* setup our fds to poll for input */
|
||||
{
|
||||
|
|
@ -4169,9 +4222,9 @@ static void mainloop(void)
|
|||
e.data.ptr = &d[i++];
|
||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, daefd, &e);
|
||||
|
||||
d[i].type = FD_TYPE_NETLINK;
|
||||
d[i].type = FD_TYPE_RTNETLINK;
|
||||
e.data.ptr = &d[i++];
|
||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, nlfd, &e);
|
||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, rtnlfd, &e);
|
||||
|
||||
d[i].type = FD_TYPE_PPPOEDISC;
|
||||
e.data.ptr = &d[i++];
|
||||
|
|
@ -4334,27 +4387,11 @@ static void mainloop(void)
|
|||
break;
|
||||
#endif /* BGP */
|
||||
|
||||
case FD_TYPE_NETLINK:
|
||||
case FD_TYPE_RTNETLINK:
|
||||
{
|
||||
struct nlmsghdr *nh = (struct nlmsghdr *)p;
|
||||
s = netlink_recv(p, size_bufp);
|
||||
if (nh->nlmsg_type == NLMSG_ERROR)
|
||||
{
|
||||
struct nlmsgerr *errmsg = NLMSG_DATA(nh);
|
||||
if (errmsg->error)
|
||||
{
|
||||
if (errmsg->msg.nlmsg_seq < min_initok_nlseqnum)
|
||||
{
|
||||
LOG(0, 0, 0, "Got a fatal netlink error (while %s): %s\n", tun_nl_phase_msg[nh->nlmsg_seq], strerror(-errmsg->error));
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
LOG(0, 0, 0, "Got a netlink error: %s\n", strerror(-errmsg->error));
|
||||
}
|
||||
// else it's a ack
|
||||
}
|
||||
else
|
||||
LOG(1, 0, 0, "Got a unknown netlink message: type %d seq %d flags %d\n", nh->nlmsg_type, nh->nlmsg_seq, nh->nlmsg_flags);
|
||||
s = rtnetlink_recv(p, size_bufp);
|
||||
netlink_handle_ack(nh, min_initok_rtnlseqnum, tun_rtnl_phase_msg);
|
||||
n--;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue