Project

General

Profile

Bug #6123 » 0001-add-IPv6-support.patch

pablo, 10/06/2023 10:07 AM

View differences:

include/linux/gtp.h
1
#ifndef _UAPI_LINUX_GTP_H_
2
#define _UAPI_LINUX_GTP_H__
1
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2
#ifndef __LINUX_GTP_H_
3
#define __LINUX_GTP_H_
4

  
5
#define GTP_GENL_MCGRP_NAME	"gtp"
3 6

  
4 7
enum gtp_genl_cmds {
5 8
	GTP_CMD_NEWPDP,
6 9
	GTP_CMD_DELPDP,
7 10
	GTP_CMD_GETPDP,
11
	GTP_CMD_ECHOREQ,
8 12

  
9 13
	GTP_CMD_MAX,
10 14
};
......
19 23
	GTPA_LINK,
20 24
	GTPA_VERSION,
21 25
	GTPA_TID,	/* for GTPv0 only */
22
	GTPA_PEER_ADDRESS,
26
	GTPA_PEER_ADDRESS,	/* Remote GSN peer, either SGSN or GGSN */
27
#define GTPA_SGSN_ADDRESS GTPA_PEER_ADDRESS /* maintain legacy attr name */
23 28
	GTPA_MS_ADDRESS,
24 29
	GTPA_FLOW,
25 30
	GTPA_NET_NS_FD,
26 31
	GTPA_I_TEI,	/* for GTPv1 only */
27 32
	GTPA_O_TEI,	/* for GTPv1 only */
28 33
	GTPA_PAD,
34
	GTPA_PEER_ADDR6,	/* Remote GSN peer, either SGSN or GGSN */
35
	GTPA_MS_ADDR6,
36
	GTPA_FAMILY,
29 37
	__GTPA_MAX,
30 38
};
31 39
#define GTPA_MAX (__GTPA_MAX + 1)
32 40

  
33
#endif /* _UAPI_LINUX_GTP_H_ */
41
#endif /* __LINUX_GTP_H_ */
src/gtp-genl.c
44 44

  
45 45
static void gtp_build_payload(struct nlmsghdr *nlh, struct gtp_tunnel *t)
46 46
{
47
	mnl_attr_put_u8(nlh, GTPA_FAMILY, t->family);
47 48
	mnl_attr_put_u32(nlh, GTPA_VERSION, t->gtp_version);
48 49
	if (t->ifns >= 0)
49 50
		mnl_attr_put_u32(nlh, GTPA_NET_NS_FD, t->ifns);
50 51
	mnl_attr_put_u32(nlh, GTPA_LINK, t->ifidx);
51
	if (t->ip.sgsn_addr.s_addr)
52
		mnl_attr_put_u32(nlh, GTPA_PEER_ADDRESS, t->ip.sgsn_addr.s_addr);
53
	if (t->ip.ms_addr.s_addr)
54
		mnl_attr_put_u32(nlh, GTPA_MS_ADDRESS, t->ip.ms_addr.s_addr);
52
	switch (t->family) {
53
	case AF_INET:
54
		if (t->ip.sgsn_addr.s_addr)
55
			mnl_attr_put_u32(nlh, GTPA_PEER_ADDRESS, t->ip.sgsn_addr.s_addr);
56
		if (t->ip.ms_addr.s_addr)
57
			mnl_attr_put_u32(nlh, GTPA_MS_ADDRESS, t->ip.ms_addr.s_addr);
58
		break;
59
	case AF_INET6:
60
		mnl_attr_put(nlh, GTPA_PEER_ADDR6, sizeof(t->ip6.sgsn_addr), &t->ip6.sgsn_addr);
61
		mnl_attr_put(nlh, GTPA_MS_ADDR6, sizeof(t->ip6.ms_addr), &t->ip6.ms_addr);
62
		break;
63
	}
55 64
	if (t->gtp_version == GTP_V0) {
56 65
		mnl_attr_put_u64(nlh, GTPA_TID, t->u.v0.tid);
57 66
		mnl_attr_put_u16(nlh, GTPA_FLOW, t->u.v0.flowid);
......
106 115
EXPORT_SYMBOL(gtp_del_tunnel);
107 116

  
108 117
struct gtp_pdp {
118
	int 		family;
109 119
	uint32_t	version;
110 120
	union {
111 121
		struct {
......
121 131
			struct in_addr	sgsn_addr;
122 132
			struct in_addr	ms_addr;
123 133
		} ip;
134
		struct {
135
			struct in6_addr	sgsn_addr;
136
			struct in6_addr	ms_addr;
137
		} ip6;
124 138
	};
125 139
};
126 140

  
......
133 147
		return MNL_CB_OK;
134 148

  
135 149
	switch(type) {
150
	case GTPA_FAMILY:
151
		if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
152
			perror("mnl_attr_validate");
153
			return MNL_CB_ERROR;
154
		}
155
		break;
136 156
	case GTPA_TID:
137 157
		if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
138 158
			perror("mnl_attr_validate");
......
149 169
			return MNL_CB_ERROR;
150 170
		}
151 171
		break;
172
	case GTPA_PEER_ADDR6:
173
	case GTPA_MS_ADDR6:
174
		if (mnl_attr_validate2(attr, MNL_TYPE_BINARY,
175
				       sizeof(struct in6_addr)) < 0) {
176
			perror("mnl_attr_validate");
177
			return MNL_CB_ERROR;
178
		}
179
		break;
152 180
	default:
153 181
		break;
154 182
	}
......
164 192
	struct genlmsghdr *genl;
165 193

  
166 194
	mnl_attr_parse(nlh, sizeof(*genl), genl_gtp_validate_cb, tb);
195
	if (tb[GTPA_FAMILY])
196
		pdp.family = mnl_attr_get_u32(tb[GTPA_FAMILY]);
197
	else
198
		pdp.family = AF_INET;
199

  
167 200
	if (tb[GTPA_TID])
168 201
		pdp.u.v0.tid = mnl_attr_get_u64(tb[GTPA_TID]);
169 202
	if (tb[GTPA_I_TEI])
170 203
		pdp.u.v1.i_tei = mnl_attr_get_u32(tb[GTPA_I_TEI]);
171 204
	if (tb[GTPA_O_TEI])
172 205
		pdp.u.v1.o_tei = mnl_attr_get_u32(tb[GTPA_O_TEI]);
173
	if (tb[GTPA_PEER_ADDRESS]) {
174
		pdp.ip.sgsn_addr.s_addr =
175
			mnl_attr_get_u32(tb[GTPA_PEER_ADDRESS]);
176
	}
177
	if (tb[GTPA_MS_ADDRESS]) {
178
		pdp.ip.ms_addr.s_addr = mnl_attr_get_u32(tb[GTPA_MS_ADDRESS]);
206

  
207
	switch (pdp.family) {
208
	case AF_INET:
209
		if (tb[GTPA_PEER_ADDRESS]) {
210
			pdp.ip.sgsn_addr.s_addr =
211
				mnl_attr_get_u32(tb[GTPA_PEER_ADDRESS]);
212
		}
213
		if (tb[GTPA_MS_ADDRESS]) {
214
			pdp.ip.ms_addr.s_addr = mnl_attr_get_u32(tb[GTPA_MS_ADDRESS]);
215
		}
216
		break;
217
	case AF_INET6:
218
		if (tb[GTPA_PEER_ADDR6])
219
			memcpy(&pdp.ip6.sgsn_addr, mnl_attr_get_payload(tb[GTPA_PEER_ADDR6]), sizeof(struct in6_addr));
220
		if (tb[GTPA_MS_ADDR6])
221
			memcpy(&pdp.ip6.ms_addr, mnl_attr_get_payload(tb[GTPA_MS_ADDR6]), sizeof(struct in6_addr));
222
		break;
179 223
	}
180
	if (tb[GTPA_VERSION]) {
224
	if (tb[GTPA_VERSION])
181 225
		pdp.version = mnl_attr_get_u32(tb[GTPA_VERSION]);
182
	}
183 226

  
184 227
	printf("version %u ", pdp.version);
185
	if (pdp.version == GTP_V0) {
186
		inet_ntop(AF_INET, &pdp.ip.ms_addr, buf, sizeof(buf));
187
		printf("tid %"PRIu64" ms_addr %s ",
188
		       pdp.u.v0.tid, buf);
189
	} else if (pdp.version == GTP_V1) {
228

  
229
	if (pdp.version == GTP_V0)
230
		printf("tid %"PRIu64" ", pdp.u.v0.tid);
231
	else if (pdp.version == GTP_V1)
232
		printf("tei %u/%u ", pdp.u.v1.i_tei, pdp.u.v1.o_tei);
233

  
234
	printf("family %s ", pdp.family == AF_INET6 ? "ip6" : "ip");
235

  
236
	switch (pdp.family) {
237
	case AF_INET:
190 238
		inet_ntop(AF_INET, &pdp.ip.ms_addr, buf, sizeof(buf));
191
		printf("tei %u/%u ms_addr %s ", pdp.u.v1.i_tei,
192
		       pdp.u.v1.o_tei, buf);
239
		printf("ms_addr %s ", buf);
240
		inet_ntop(AF_INET, &pdp.ip.sgsn_addr, buf, sizeof(buf));
241
		printf("sgsn_addr %s\n", buf);
242
		break;
243
	case AF_INET6:
244
		inet_ntop(AF_INET6, &pdp.ip6.ms_addr, buf, sizeof(buf));
245
		printf("ms_addr6 %s ", buf);
246
		inet_ntop(AF_INET6, &pdp.ip6.sgsn_addr, buf, sizeof(buf));
247
		printf("sgsn_addr6 %s\n", buf);
248
		break;
193 249
	}
194
	inet_ntop(AF_INET, &pdp.ip.sgsn_addr, buf, sizeof(buf));
195
	printf("sgsn_addr %s\n", buf);
196 250

  
197 251
	return MNL_CB_OK;
198 252
}
src/internal.h
13 13
#include <netinet/in.h>
14 14

  
15 15
struct gtp_tunnel {
16
	uint8_t		family;
16 17
	int             ifns;
17 18
	uint32_t	ifidx;
18 19
	union {
......
20 21
			struct in_addr	ms_addr;
21 22
			struct in_addr	sgsn_addr;
22 23
		} ip;
24
		struct {
25
			struct in6_addr	ms_addr;
26
			struct in6_addr	sgsn_addr;
27
		} ip6;
23 28
	};
24 29
	int		gtp_version;
25 30
	union {
(3-3/7)
Add picture from clipboard (Maximum size: 48.8 MB)