Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/netlink/test_rtnl_gre.c
178478 views
1
/*
2
* Copyright (c) 2026 Pouria Mousavizadeh Tehrani <[email protected]>
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*/
6
7
#include <sys/param.h>
8
#include <sys/module.h>
9
#include <sys/types.h>
10
#include <sys/socket.h>
11
#include <netinet/in.h>
12
#include <arpa/inet.h>
13
#include <net/if_gre.h>
14
15
#include <netlink/netlink.h>
16
#include <netlink/netlink_route.h>
17
#include "netlink/netlink_snl.h"
18
#include <netlink/netlink_snl_route.h>
19
#include <netlink/netlink_snl_route_compat.h>
20
#include <netlink/netlink_snl_route_parsers.h>
21
22
#include <atf-c.h>
23
24
struct nl_parsed_gre {
25
struct sockaddr *ifla_local;
26
struct sockaddr *ifla_remote;
27
uint32_t ifla_flags;
28
uint32_t ifla_okey;
29
uint32_t ifla_encap_type;
30
uint16_t ifla_encap_sport;
31
};
32
33
struct nla_gre_info {
34
const char *kind;
35
struct nl_parsed_gre data;
36
};
37
38
struct nla_gre_link {
39
uint32_t ifi_index;
40
struct nla_gre_info linkinfo;
41
};
42
43
#define _OUT(_field) offsetof(struct nl_parsed_gre, _field)
44
static const struct snl_attr_parser nla_p_gre[] = {
45
{ .type = IFLA_GRE_LOCAL, .off = _OUT(ifla_local), .cb = snl_attr_get_ip },
46
{ .type = IFLA_GRE_REMOTE, .off = _OUT(ifla_remote), .cb = snl_attr_get_ip },
47
{ .type = IFLA_GRE_FLAGS, .off = _OUT(ifla_flags), .cb = snl_attr_get_uint32 },
48
{ .type = IFLA_GRE_OKEY, .off = _OUT(ifla_okey), .cb = snl_attr_get_uint32 },
49
{ .type = IFLA_GRE_ENCAP_TYPE, .off = _OUT(ifla_encap_type), .cb = snl_attr_get_uint32 },
50
{ .type = IFLA_GRE_ENCAP_SPORT, .off = _OUT(ifla_encap_sport), .cb = snl_attr_get_uint16 },
51
};
52
#undef _OUT
53
SNL_DECLARE_ATTR_PARSER(gre_linkinfo_data_parser, nla_p_gre);
54
55
#define _OUT(_field) offsetof(struct nla_gre_info, _field)
56
static const struct snl_attr_parser ap_gre_linkinfo[] = {
57
{ .type = IFLA_INFO_KIND, .off = _OUT(kind), .cb = snl_attr_get_string },
58
{ .type = IFLA_INFO_DATA, .off = _OUT(data),
59
.arg = &gre_linkinfo_data_parser, .cb = snl_attr_get_nested },
60
};
61
#undef _OUT
62
SNL_DECLARE_ATTR_PARSER(gre_linkinfo_parser, ap_gre_linkinfo);
63
64
#define _IN(_field) offsetof(struct ifinfomsg, _field)
65
#define _OUT(_field) offsetof(struct nla_gre_link, _field)
66
static const struct snl_attr_parser ap_gre_link[] = {
67
{ .type = IFLA_LINKINFO, .off = _OUT(linkinfo),
68
.arg = &gre_linkinfo_parser, .cb = snl_attr_get_nested },
69
};
70
71
static const struct snl_field_parser fp_gre_link[] = {
72
{ .off_in = _IN(ifi_index), .off_out = _OUT(ifi_index), .cb = snl_field_get_uint32 },
73
};
74
#undef _IN
75
#undef _OUT
76
SNL_DECLARE_PARSER(gre_parser, struct ifinfomsg, fp_gre_link, ap_gre_link);
77
78
ATF_TC(test_rtnl_gre);
79
ATF_TC_HEAD(test_rtnl_gre, tc)
80
{
81
atf_tc_set_md_var(tc, "descr", "test gre interface using netlink");
82
atf_tc_set_md_var(tc, "require.user", "root");
83
atf_tc_set_md_var(tc, "require.kmods", "netlink if_gre");
84
}
85
86
ATF_TC_BODY(test_rtnl_gre, tc)
87
{
88
struct snl_state ss;
89
struct snl_writer nw;
90
struct nlmsghdr *hdr, *rx_hdr;
91
struct in_addr src, dst;
92
struct nla_gre_link lattrs = {};
93
struct nl_parsed_gre attrs = {};
94
struct snl_errmsg_data e = {};
95
struct ifinfomsg *ifmsg;
96
int off, off2;
97
98
ATF_REQUIRE_MSG(snl_init(&ss, NETLINK_ROUTE), "snl_init() failed");
99
100
/* Create gre interface */
101
snl_init_writer(&ss, &nw);
102
ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_NEWLINK)) != NULL);
103
hdr->nlmsg_flags |= (NLM_F_CREATE | NLM_F_EXCL | NLM_F_REQUEST | NLM_F_ACK);
104
snl_reserve_msg_object(&nw, struct ifinfomsg);
105
106
/* Create parameters */
107
snl_add_msg_attr_string(&nw, IFLA_IFNAME, "gre10");
108
off = snl_add_msg_attr_nested(&nw, IFLA_LINKINFO);
109
snl_add_msg_attr_string(&nw, IFLA_INFO_KIND, "gre");
110
off2 = snl_add_msg_attr_nested(&nw, IFLA_INFO_DATA);
111
112
inet_pton(AF_INET, "127.0.0.1", &src);
113
inet_pton(AF_INET, "127.0.0.2", &dst);
114
snl_add_msg_attr_ip4(&nw, IFLA_GRE_LOCAL, &src);
115
snl_add_msg_attr_ip4(&nw, IFLA_GRE_REMOTE, &dst);
116
snl_add_msg_attr_u32(&nw, IFLA_GRE_FLAGS, (GRE_ENABLE_SEQ | GRE_ENABLE_CSUM));
117
snl_add_msg_attr_u32(&nw, IFLA_GRE_OKEY, 123456);
118
snl_add_msg_attr_u32(&nw, IFLA_GRE_ENCAP_TYPE, IFLA_TUNNEL_GRE_UDP);
119
snl_add_msg_attr_u16(&nw, IFLA_GRE_ENCAP_SPORT, 50000);
120
121
snl_end_attr_nested(&nw, off2);
122
snl_end_attr_nested(&nw, off);
123
124
ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL);
125
ATF_REQUIRE(snl_send_message(&ss, hdr));
126
ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL);
127
ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e));
128
ATF_REQUIRE_INTEQ(e.error, 0);
129
130
/* Dump gre interface */
131
snl_init_writer(&ss, &nw);
132
ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_GETLINK)) != NULL);
133
hdr->nlmsg_flags |= NLM_F_DUMP;
134
snl_reserve_msg_object(&nw, struct ifinfomsg);
135
snl_add_msg_attr_string(&nw, IFLA_IFNAME, "gre10");
136
off = snl_add_msg_attr_nested(&nw, IFLA_LINKINFO);
137
snl_add_msg_attr_string(&nw, IFLA_INFO_KIND, "gre");
138
snl_end_attr_nested(&nw, off);
139
140
ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL);
141
ATF_REQUIRE(snl_send_message(&ss, hdr));
142
143
/* Check parameters */
144
ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL);
145
ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &gre_parser, &lattrs));
146
attrs = lattrs.linkinfo.data;
147
ATF_CHECK_STREQ(lattrs.linkinfo.kind, "gre");
148
ATF_CHECK_INTEQ(attrs.ifla_flags, (GRE_ENABLE_SEQ | GRE_ENABLE_CSUM | GRE_UDPENCAP));
149
ATF_CHECK_INTEQ(attrs.ifla_okey, 123456);
150
ATF_CHECK_INTEQ(attrs.ifla_encap_type, IFLA_TUNNEL_GRE_UDP);
151
ATF_CHECK_INTEQ(attrs.ifla_encap_sport, 50000);
152
153
/* Delete gre interface */
154
snl_init_writer(&ss, &nw);
155
ATF_REQUIRE((hdr = snl_create_msg_request(&nw, RTM_DELLINK)) != NULL);
156
hdr->nlmsg_flags |= (NLM_F_ACK | NLM_F_REQUEST);
157
ATF_REQUIRE((ifmsg = snl_reserve_msg_object(&nw, struct ifinfomsg)) != NULL);
158
ifmsg->ifi_index = lattrs.ifi_index;
159
ATF_REQUIRE((hdr = snl_finalize_msg(&nw)) != NULL);
160
ATF_REQUIRE(snl_send_message(&ss, hdr));
161
ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL);
162
ATF_REQUIRE(snl_parse_errmsg(&ss, rx_hdr, &e));
163
ATF_REQUIRE_INTEQ(e.error, 0);
164
}
165
166
ATF_TP_ADD_TCS(tp)
167
{
168
ATF_TP_ADD_TC(tp, test_rtnl_gre);
169
170
return (atf_no_error());
171
}
172
173
174