]>
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 <netinet/in.h>
11 #include <linux/netlink.h>
12 #include <linux/rtnetlink.h>
15 #include <linux/ipv6.h>
16 #include <linux/if_tunnel.h>
22 static int __netlink_gre_get_data(struct zbuf
*zb
, struct zbuf
*data
, int ifindex
)
25 struct ifinfomsg
*ifi
;
26 struct zbuf payload
, rtapayload
;
29 debugf(NHRP_DEBUG_KERNEL
, "netlink-link-gre: get-info %u", ifindex
);
31 n
= znl_nlmsg_push(zb
, RTM_GETLINK
, NLM_F_REQUEST
);
32 ifi
= znl_push(zb
, sizeof(*ifi
));
33 *ifi
= (struct ifinfomsg
) {
36 znl_nlmsg_complete(zb
, n
);
38 if (zbuf_send(zb
, netlink_req_fd
) < 0 ||
39 zbuf_recv(zb
, netlink_req_fd
) < 0)
42 n
= znl_nlmsg_pull(zb
, &payload
);
45 if (n
->nlmsg_type
!= RTM_NEWLINK
)
48 ifi
= znl_pull(&payload
, sizeof(struct ifinfomsg
));
52 debugf(NHRP_DEBUG_KERNEL
, "netlink-link-gre: ifindex %u, receive msg_type %u, msg_flags %u",
53 ifi
->ifi_index
, n
->nlmsg_type
, n
->nlmsg_flags
);
55 if (ifi
->ifi_index
!= ifindex
)
58 while ((rta
= znl_rta_pull(&payload
, &rtapayload
)) != NULL
)
59 if (rta
->rta_type
== IFLA_LINKINFO
)
64 while ((rta
= znl_rta_pull(&payload
, &rtapayload
)) != NULL
)
65 if (rta
->rta_type
== IFLA_INFO_DATA
)
73 void netlink_gre_get_info(unsigned int ifindex
, uint32_t *gre_key
, unsigned int *link_index
, struct in_addr
*saddr
)
75 struct zbuf
*zb
= zbuf_alloc(8192), data
, rtapl
;
82 if (__netlink_gre_get_data(zb
, &data
, ifindex
) < 0)
85 while ((rta
= znl_rta_pull(&data
, &rtapl
)) != NULL
) {
86 switch (rta
->rta_type
) {
88 *link_index
= zbuf_get32(&rtapl
);
92 *gre_key
= zbuf_get32(&rtapl
);
95 saddr
->s_addr
= zbuf_get32(&rtapl
);
103 void netlink_gre_set_link(unsigned int ifindex
, unsigned int link_index
)
106 struct ifinfomsg
*ifi
;
107 struct rtattr
*rta_info
, *rta_data
, *rta
;
108 struct zbuf
*zr
= zbuf_alloc(8192), data
, rtapl
;
109 struct zbuf
*zb
= zbuf_alloc(8192);
112 if (__netlink_gre_get_data(zr
, &data
, ifindex
) < 0)
115 n
= znl_nlmsg_push(zb
, RTM_NEWLINK
, NLM_F_REQUEST
);
116 ifi
= znl_push(zb
, sizeof(*ifi
));
117 *ifi
= (struct ifinfomsg
) {
118 .ifi_index
= ifindex
,
120 rta_info
= znl_rta_nested_push(zb
, IFLA_LINKINFO
);
121 znl_rta_push(zb
, IFLA_INFO_KIND
, "gre", 3);
122 rta_data
= znl_rta_nested_push(zb
, IFLA_INFO_DATA
);
124 znl_rta_push_u32(zb
, IFLA_GRE_LINK
, link_index
);
125 while ((rta
= znl_rta_pull(&data
, &rtapl
)) != NULL
) {
126 if (rta
->rta_type
== IFLA_GRE_LINK
)
128 len
= zbuf_used(&rtapl
);
129 znl_rta_push(zb
, rta
->rta_type
, zbuf_pulln(&rtapl
, len
), len
);
132 znl_rta_nested_complete(zb
, rta_data
);
133 znl_rta_nested_complete(zb
, rta_info
);
135 znl_nlmsg_complete(zb
, n
);
136 zbuf_send(zb
, netlink_req_fd
);
137 zbuf_recv(zb
, netlink_req_fd
);