Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gtp: Implement GTP echo response

Adding GTP device through ip link creates the situation where
there is no userspace daemon which would handle GTP messages
(Echo Request for example). GTP-U instance which would not respond
to echo requests would violate GTP specification.

When GTP packet arrives with GTP_ECHO_REQ message type,
GTP_ECHO_RSP is send to the sender. GTP_ECHO_RSP message
should contain information element with GTPIE_RECOVERY tag and
restart counter value. For GTPv1 restart counter is not used
and should be equal to 0, for GTPv0 restart counter contains
information provided from userspace(IFLA_GTP_RESTART_COUNT).

Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
Suggested-by: Harald Welte <laforge@gnumonks.org>
Reviewed-by: Harald Welte <laforge@gnumonks.org>
Tested-by: Harald Welte <laforge@gnumonks.org>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

authored by

Wojciech Drewek and committed by
Tony Nguyen
9af41cc3 b20dc3c6

+229 -16
+197 -16
drivers/net/gtp.c
··· 75 75 unsigned int hash_size; 76 76 struct hlist_head *tid_hash; 77 77 struct hlist_head *addr_hash; 78 + 79 + u8 restart_count; 78 80 }; 79 81 80 82 static unsigned int gtp_net_id __read_mostly; ··· 219 217 return -1; 220 218 } 221 219 220 + static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4, 221 + const struct sock *sk, 222 + __be32 daddr, __be32 saddr) 223 + { 224 + memset(fl4, 0, sizeof(*fl4)); 225 + fl4->flowi4_oif = sk->sk_bound_dev_if; 226 + fl4->daddr = daddr; 227 + fl4->saddr = saddr; 228 + fl4->flowi4_tos = RT_CONN_FLAGS(sk); 229 + fl4->flowi4_proto = sk->sk_protocol; 230 + 231 + return ip_route_output_key(sock_net(sk), fl4); 232 + } 233 + 234 + /* GSM TS 09.60. 7.3 235 + * In all Path Management messages: 236 + * - TID: is not used and shall be set to 0. 237 + * - Flow Label is not used and shall be set to 0 238 + * In signalling messages: 239 + * - number: this field is not yet used in signalling messages. 240 + * It shall be set to 255 by the sender and shall be ignored 241 + * by the receiver 242 + * Returns true if the echo req was correct, false otherwise. 243 + */ 244 + static bool gtp0_validate_echo_req(struct gtp0_header *gtp0) 245 + { 246 + return !(gtp0->tid || (gtp0->flags ^ 0x1e) || 247 + gtp0->number != 0xff || gtp0->flow); 248 + } 249 + 250 + static int gtp0_send_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb) 251 + { 252 + struct gtp0_packet *gtp_pkt; 253 + struct gtp0_header *gtp0; 254 + struct rtable *rt; 255 + struct flowi4 fl4; 256 + struct iphdr *iph; 257 + __be16 seq; 258 + 259 + gtp0 = (struct gtp0_header *)(skb->data + sizeof(struct udphdr)); 260 + 261 + if (!gtp0_validate_echo_req(gtp0)) 262 + return -1; 263 + 264 + seq = gtp0->seq; 265 + 266 + /* pull GTP and UDP headers */ 267 + skb_pull_data(skb, sizeof(struct gtp0_header) + sizeof(struct udphdr)); 268 + 269 + gtp_pkt = skb_push(skb, sizeof(struct gtp0_packet)); 270 + memset(gtp_pkt, 0, sizeof(struct gtp0_packet)); 271 + 272 + gtp_pkt->gtp0_h.flags = 0x1e; /* v0, GTP-non-prime. */ 273 + gtp_pkt->gtp0_h.type = GTP_ECHO_RSP; 274 + gtp_pkt->gtp0_h.length = 275 + htons(sizeof(struct gtp0_packet) - sizeof(struct gtp0_header)); 276 + 277 + /* GSM TS 09.60. 7.3 The Sequence Number in a signalling response 278 + * message shall be copied from the signalling request message 279 + * that the GSN is replying to. 280 + */ 281 + gtp_pkt->gtp0_h.seq = seq; 282 + 283 + /* GSM TS 09.60. 7.3 In all Path Management Flow Label and TID 284 + * are not used and shall be set to 0. 285 + */ 286 + gtp_pkt->gtp0_h.flow = 0; 287 + gtp_pkt->gtp0_h.tid = 0; 288 + gtp_pkt->gtp0_h.number = 0xff; 289 + gtp_pkt->gtp0_h.spare[0] = 0xff; 290 + gtp_pkt->gtp0_h.spare[1] = 0xff; 291 + gtp_pkt->gtp0_h.spare[2] = 0xff; 292 + 293 + gtp_pkt->ie.tag = GTPIE_RECOVERY; 294 + gtp_pkt->ie.val = gtp->restart_count; 295 + 296 + iph = ip_hdr(skb); 297 + 298 + /* find route to the sender, 299 + * src address becomes dst address and vice versa. 300 + */ 301 + rt = ip4_route_output_gtp(&fl4, gtp->sk0, iph->saddr, iph->daddr); 302 + if (IS_ERR(rt)) { 303 + netdev_dbg(gtp->dev, "no route for echo response from %pI4\n", 304 + &iph->saddr); 305 + return -1; 306 + } 307 + 308 + udp_tunnel_xmit_skb(rt, gtp->sk0, skb, 309 + fl4.saddr, fl4.daddr, 310 + iph->tos, 311 + ip4_dst_hoplimit(&rt->dst), 312 + 0, 313 + htons(GTP0_PORT), htons(GTP0_PORT), 314 + !net_eq(sock_net(gtp->sk1u), 315 + dev_net(gtp->dev)), 316 + false); 317 + return 0; 318 + } 319 + 222 320 /* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */ 223 321 static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb) 224 322 { ··· 335 233 if ((gtp0->flags >> 5) != GTP_V0) 336 234 return 1; 337 235 236 + /* If the sockets were created in kernel, it means that 237 + * there is no daemon running in userspace which would 238 + * handle echo request. 239 + */ 240 + if (gtp0->type == GTP_ECHO_REQ && gtp->sk_created) 241 + return gtp0_send_echo_resp(gtp, skb); 242 + 338 243 if (gtp0->type != GTP_TPDU) 339 244 return 1; 340 245 ··· 352 243 } 353 244 354 245 return gtp_rx(pctx, skb, hdrlen, gtp->role); 246 + } 247 + 248 + static int gtp1u_send_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb) 249 + { 250 + struct gtp1_header_long *gtp1u; 251 + struct gtp1u_packet *gtp_pkt; 252 + struct rtable *rt; 253 + struct flowi4 fl4; 254 + struct iphdr *iph; 255 + 256 + gtp1u = (struct gtp1_header_long *)(skb->data + sizeof(struct udphdr)); 257 + 258 + /* 3GPP TS 29.281 5.1 - For the Echo Request, Echo Response, 259 + * Error Indication and Supported Extension Headers Notification 260 + * messages, the S flag shall be set to 1 and TEID shall be set to 0. 261 + */ 262 + if (!(gtp1u->flags & GTP1_F_SEQ) || gtp1u->tid) 263 + return -1; 264 + 265 + /* pull GTP and UDP headers */ 266 + skb_pull_data(skb, 267 + sizeof(struct gtp1_header_long) + sizeof(struct udphdr)); 268 + 269 + gtp_pkt = skb_push(skb, sizeof(struct gtp1u_packet)); 270 + memset(gtp_pkt, 0, sizeof(struct gtp1u_packet)); 271 + 272 + /* S flag must be set to 1 */ 273 + gtp_pkt->gtp1u_h.flags = 0x32; 274 + gtp_pkt->gtp1u_h.type = GTP_ECHO_RSP; 275 + /* seq, npdu and next should be counted to the length of the GTP packet 276 + * that's why szie of gtp1_header should be subtracted, 277 + * not why szie of gtp1_header_long. 278 + */ 279 + gtp_pkt->gtp1u_h.length = 280 + htons(sizeof(struct gtp1u_packet) - sizeof(struct gtp1_header)); 281 + /* 3GPP TS 29.281 5.1 - TEID has to be set to 0 */ 282 + gtp_pkt->gtp1u_h.tid = 0; 283 + 284 + /* 3GPP TS 29.281 7.7.2 - The Restart Counter value in the 285 + * Recovery information element shall not be used, i.e. it shall 286 + * be set to zero by the sender and shall be ignored by the receiver. 287 + * The Recovery information element is mandatory due to backwards 288 + * compatibility reasons. 289 + */ 290 + gtp_pkt->ie.tag = GTPIE_RECOVERY; 291 + gtp_pkt->ie.val = 0; 292 + 293 + iph = ip_hdr(skb); 294 + 295 + /* find route to the sender, 296 + * src address becomes dst address and vice versa. 297 + */ 298 + rt = ip4_route_output_gtp(&fl4, gtp->sk1u, iph->saddr, iph->daddr); 299 + if (IS_ERR(rt)) { 300 + netdev_dbg(gtp->dev, "no route for echo response from %pI4\n", 301 + &iph->saddr); 302 + return -1; 303 + } 304 + 305 + udp_tunnel_xmit_skb(rt, gtp->sk1u, skb, 306 + fl4.saddr, fl4.daddr, 307 + iph->tos, 308 + ip4_dst_hoplimit(&rt->dst), 309 + 0, 310 + htons(GTP1U_PORT), htons(GTP1U_PORT), 311 + !net_eq(sock_net(gtp->sk1u), 312 + dev_net(gtp->dev)), 313 + false); 314 + return 0; 355 315 } 356 316 357 317 static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb) ··· 437 259 438 260 if ((gtp1->flags >> 5) != GTP_V1) 439 261 return 1; 262 + 263 + /* If the sockets were created in kernel, it means that 264 + * there is no daemon running in userspace which would 265 + * handle echo request. 266 + */ 267 + if (gtp1->type == GTP_ECHO_REQ && gtp->sk_created) 268 + return gtp1u_send_echo_resp(gtp, skb); 440 269 441 270 if (gtp1->type != GTP_TPDU) 442 271 return 1; ··· 583 398 free_percpu(dev->tstats); 584 399 } 585 400 586 - static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4, 587 - const struct sock *sk, 588 - __be32 daddr) 589 - { 590 - memset(fl4, 0, sizeof(*fl4)); 591 - fl4->flowi4_oif = sk->sk_bound_dev_if; 592 - fl4->daddr = daddr; 593 - fl4->saddr = inet_sk(sk)->inet_saddr; 594 - fl4->flowi4_tos = RT_CONN_FLAGS(sk); 595 - fl4->flowi4_proto = sk->sk_protocol; 596 - 597 - return ip_route_output_key(sock_net(sk), fl4); 598 - } 599 - 600 401 static inline void gtp0_push_header(struct sk_buff *skb, struct pdp_ctx *pctx) 601 402 { 602 403 int payload_len = skb->len; ··· 688 517 } 689 518 netdev_dbg(dev, "found PDP context %p\n", pctx); 690 519 691 - rt = ip4_route_output_gtp(&fl4, pctx->sk, pctx->peer_addr_ip4.s_addr); 520 + rt = ip4_route_output_gtp(&fl4, pctx->sk, pctx->peer_addr_ip4.s_addr, 521 + inet_sk(pctx->sk)->inet_saddr); 692 522 if (IS_ERR(rt)) { 693 523 netdev_dbg(dev, "no route to SSGN %pI4\n", 694 524 &pctx->peer_addr_ip4.s_addr); ··· 918 746 } 919 747 gtp->role = role; 920 748 749 + if (!data[IFLA_GTP_RESTART_COUNT]) 750 + gtp->restart_count = 0; 751 + else 752 + gtp->restart_count = nla_get_u8(data[IFLA_GTP_RESTART_COUNT]); 753 + 921 754 gtp->net = src_net; 922 755 923 756 err = gtp_hashtable_new(gtp, hashsize); ··· 978 801 [IFLA_GTP_PDP_HASHSIZE] = { .type = NLA_U32 }, 979 802 [IFLA_GTP_ROLE] = { .type = NLA_U32 }, 980 803 [IFLA_GTP_CREATE_SOCKETS] = { .type = NLA_U8 }, 804 + [IFLA_GTP_RESTART_COUNT] = { .type = NLA_U8 }, 981 805 }; 982 806 983 807 static int gtp_validate(struct nlattr *tb[], struct nlattr *data[], ··· 993 815 static size_t gtp_get_size(const struct net_device *dev) 994 816 { 995 817 return nla_total_size(sizeof(__u32)) + /* IFLA_GTP_PDP_HASHSIZE */ 996 - nla_total_size(sizeof(__u32)); /* IFLA_GTP_ROLE */ 818 + nla_total_size(sizeof(__u32)) + /* IFLA_GTP_ROLE */ 819 + nla_total_size(sizeof(__u8)); /* IFLA_GTP_RESTART_COUNT */ 997 820 } 998 821 999 822 static int gtp_fill_info(struct sk_buff *skb, const struct net_device *dev) ··· 1004 825 if (nla_put_u32(skb, IFLA_GTP_PDP_HASHSIZE, gtp->hash_size)) 1005 826 goto nla_put_failure; 1006 827 if (nla_put_u32(skb, IFLA_GTP_ROLE, gtp->role)) 828 + goto nla_put_failure; 829 + if (nla_put_u8(skb, IFLA_GTP_RESTART_COUNT, gtp->restart_count)) 1007 830 goto nla_put_failure; 1008 831 1009 832 return 0;
+31
include/net/gtp.h
··· 7 7 #define GTP0_PORT 3386 8 8 #define GTP1U_PORT 2152 9 9 10 + /* GTP messages types */ 11 + #define GTP_ECHO_REQ 1 /* Echo Request */ 12 + #define GTP_ECHO_RSP 2 /* Echo Response */ 10 13 #define GTP_TPDU 255 14 + 15 + #define GTPIE_RECOVERY 14 11 16 12 17 struct gtp0_header { /* According to GSM TS 09.60. */ 13 18 __u8 flags; ··· 31 26 __be16 length; 32 27 __be32 tid; 33 28 } __attribute__ ((packed)); 29 + 30 + struct gtp1_header_long { /* According to 3GPP TS 29.060. */ 31 + __u8 flags; 32 + __u8 type; 33 + __be16 length; 34 + __be32 tid; 35 + __be16 seq; 36 + __u8 npdu; 37 + __u8 next; 38 + } __packed; 39 + 40 + /* GTP Information Element */ 41 + struct gtp_ie { 42 + __u8 tag; 43 + __u8 val; 44 + } __packed; 45 + 46 + struct gtp0_packet { 47 + struct gtp0_header gtp0_h; 48 + struct gtp_ie ie; 49 + } __packed; 50 + 51 + struct gtp1u_packet { 52 + struct gtp1_header_long gtp1u_h; 53 + struct gtp_ie ie; 54 + } __packed; 34 55 35 56 #define GTP1_F_NPDU 0x01 36 57 #define GTP1_F_SEQ 0x02
+1
include/uapi/linux/if_link.h
··· 888 888 IFLA_GTP_PDP_HASHSIZE, 889 889 IFLA_GTP_ROLE, 890 890 IFLA_GTP_CREATE_SOCKETS, 891 + IFLA_GTP_RESTART_COUNT, 891 892 __IFLA_GTP_MAX, 892 893 }; 893 894 #define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)