]>
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.
14 #include <sys/socket.h>
15 #include <linux/netlink.h>
16 #include <linux/rtnetlink.h>
20 #include <linux/ipv6.h>
21 #include <linux/if_tunnel.h>
27 static int __netlink_gre_get_data(struct zbuf
*zb
, struct zbuf
*data
,
31 struct ifinfomsg
*ifi
;
32 struct zbuf payload
, rtapayload
;
35 debugf(NHRP_DEBUG_KERNEL
, "netlink-link-gre: get-info %u", ifindex
);
37 n
= znl_nlmsg_push(zb
, RTM_GETLINK
, NLM_F_REQUEST
);
38 ifi
= znl_push(zb
, sizeof(*ifi
));
39 *ifi
= (struct ifinfomsg
){
42 znl_nlmsg_complete(zb
, n
);
44 if (zbuf_send(zb
, netlink_req_fd
) < 0
45 || zbuf_recv(zb
, netlink_req_fd
) < 0)
48 n
= znl_nlmsg_pull(zb
, &payload
);
52 if (n
->nlmsg_type
!= RTM_NEWLINK
)
55 ifi
= znl_pull(&payload
, sizeof(struct ifinfomsg
));
59 debugf(NHRP_DEBUG_KERNEL
,
60 "netlink-link-gre: ifindex %u, receive msg_type %u, msg_flags %u",
61 ifi
->ifi_index
, n
->nlmsg_type
, n
->nlmsg_flags
);
63 if (ifi
->ifi_index
!= ifindex
)
66 while ((rta
= znl_rta_pull(&payload
, &rtapayload
)) != NULL
)
67 if (rta
->rta_type
== IFLA_LINKINFO
)
73 while ((rta
= znl_rta_pull(&payload
, &rtapayload
)) != NULL
)
74 if (rta
->rta_type
== IFLA_INFO_DATA
)
83 void netlink_gre_get_info(unsigned int ifindex
, uint32_t *gre_key
,
84 unsigned int *link_index
, struct in_addr
*saddr
)
86 struct zbuf
*zb
= zbuf_alloc(8192), data
, rtapl
;
93 if (__netlink_gre_get_data(zb
, &data
, ifindex
) < 0)
96 while ((rta
= znl_rta_pull(&data
, &rtapl
)) != NULL
) {
97 switch (rta
->rta_type
) {
99 *link_index
= zbuf_get32(&rtapl
);
103 *gre_key
= zbuf_get32(&rtapl
);
106 saddr
->s_addr
= zbuf_get32(&rtapl
);
114 void netlink_gre_set_link(unsigned int ifindex
, unsigned int link_index
)
117 struct ifinfomsg
*ifi
;
118 struct rtattr
*rta_info
, *rta_data
, *rta
;
119 struct zbuf
*zr
= zbuf_alloc(8192), data
, rtapl
;
120 struct zbuf
*zb
= zbuf_alloc(8192);
123 if (__netlink_gre_get_data(zr
, &data
, ifindex
) < 0)
126 n
= znl_nlmsg_push(zb
, RTM_NEWLINK
, NLM_F_REQUEST
);
127 ifi
= znl_push(zb
, sizeof(*ifi
));
128 *ifi
= (struct ifinfomsg
){
129 .ifi_index
= ifindex
,
131 rta_info
= znl_rta_nested_push(zb
, IFLA_LINKINFO
);
132 znl_rta_push(zb
, IFLA_INFO_KIND
, "gre", 3);
133 rta_data
= znl_rta_nested_push(zb
, IFLA_INFO_DATA
);
135 znl_rta_push_u32(zb
, IFLA_GRE_LINK
, link_index
);
136 while ((rta
= znl_rta_pull(&data
, &rtapl
)) != NULL
) {
137 if (rta
->rta_type
== IFLA_GRE_LINK
)
139 len
= zbuf_used(&rtapl
);
140 znl_rta_push(zb
, rta
->rta_type
, zbuf_pulln(&rtapl
, len
), len
);
143 znl_rta_nested_complete(zb
, rta_data
);
144 znl_rta_nested_complete(zb
, rta_info
);
146 znl_nlmsg_complete(zb
, n
);
147 zbuf_send(zb
, netlink_req_fd
);
148 zbuf_recv(zb
, netlink_req_fd
);