]>
git.proxmox.com Git - mirror_frr.git/blob - nhrpd/netlink_gre.c
1 /* NHRP netlink/GRE tunnel configuration code
2 * Copyright (c) 2014-2016 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.
10 #include <sys/socket.h>
11 #include <linux/netlink.h>
12 #include <linux/rtnetlink.h>
16 #include <linux/ipv6.h>
17 #include <linux/if_tunnel.h>
23 static int __netlink_gre_get_data(struct zbuf
*zb
, struct zbuf
*data
,
27 struct ifinfomsg
*ifi
;
28 struct zbuf payload
, rtapayload
;
31 debugf(NHRP_DEBUG_KERNEL
, "netlink-link-gre: get-info %u", ifindex
);
33 n
= znl_nlmsg_push(zb
, RTM_GETLINK
, NLM_F_REQUEST
);
34 ifi
= znl_push(zb
, sizeof(*ifi
));
35 *ifi
= (struct ifinfomsg
){
38 znl_nlmsg_complete(zb
, n
);
40 if (zbuf_send(zb
, netlink_req_fd
) < 0
41 || zbuf_recv(zb
, netlink_req_fd
) < 0)
44 n
= znl_nlmsg_pull(zb
, &payload
);
48 if (n
->nlmsg_type
!= RTM_NEWLINK
)
51 ifi
= znl_pull(&payload
, sizeof(struct ifinfomsg
));
55 debugf(NHRP_DEBUG_KERNEL
,
56 "netlink-link-gre: ifindex %u, receive msg_type %u, msg_flags %u",
57 ifi
->ifi_index
, n
->nlmsg_type
, n
->nlmsg_flags
);
59 if (ifi
->ifi_index
!= ifindex
)
62 while ((rta
= znl_rta_pull(&payload
, &rtapayload
)) != NULL
)
63 if (rta
->rta_type
== IFLA_LINKINFO
)
69 while ((rta
= znl_rta_pull(&payload
, &rtapayload
)) != NULL
)
70 if (rta
->rta_type
== IFLA_INFO_DATA
)
79 void netlink_gre_get_info(unsigned int ifindex
, uint32_t *gre_key
,
80 unsigned int *link_index
, struct in_addr
*saddr
)
82 struct zbuf
*zb
= zbuf_alloc(8192), data
, rtapl
;
89 if (__netlink_gre_get_data(zb
, &data
, ifindex
) < 0)
92 while ((rta
= znl_rta_pull(&data
, &rtapl
)) != NULL
) {
93 switch (rta
->rta_type
) {
95 *link_index
= zbuf_get32(&rtapl
);
99 *gre_key
= zbuf_get32(&rtapl
);
102 saddr
->s_addr
= zbuf_get32(&rtapl
);
110 void netlink_gre_set_link(unsigned int ifindex
, unsigned int link_index
)
113 struct ifinfomsg
*ifi
;
114 struct rtattr
*rta_info
, *rta_data
, *rta
;
115 struct zbuf
*zr
= zbuf_alloc(8192), data
, rtapl
;
116 struct zbuf
*zb
= zbuf_alloc(8192);
119 if (__netlink_gre_get_data(zr
, &data
, ifindex
) < 0)
122 n
= znl_nlmsg_push(zb
, RTM_NEWLINK
, NLM_F_REQUEST
);
123 ifi
= znl_push(zb
, sizeof(*ifi
));
124 *ifi
= (struct ifinfomsg
){
125 .ifi_index
= ifindex
,
127 rta_info
= znl_rta_nested_push(zb
, IFLA_LINKINFO
);
128 znl_rta_push(zb
, IFLA_INFO_KIND
, "gre", 3);
129 rta_data
= znl_rta_nested_push(zb
, IFLA_INFO_DATA
);
131 znl_rta_push_u32(zb
, IFLA_GRE_LINK
, link_index
);
132 while ((rta
= znl_rta_pull(&data
, &rtapl
)) != NULL
) {
133 if (rta
->rta_type
== IFLA_GRE_LINK
)
135 len
= zbuf_used(&rtapl
);
136 znl_rta_push(zb
, rta
->rta_type
, zbuf_pulln(&rtapl
, len
), len
);
139 znl_rta_nested_complete(zb
, rta_data
);
140 znl_rta_nested_complete(zb
, rta_info
);
142 znl_nlmsg_complete(zb
, n
);
143 zbuf_send(zb
, netlink_req_fd
);
144 zbuf_recv(zb
, netlink_req_fd
);