Skip to content

Commit faf3642

Browse files
authored
Merge pull request #40 from OpenCloudOS/dev
IPv6 support for ICMP and address filter
2 parents b7b5190 + 9b510b4 commit faf3642

14 files changed

Lines changed: 171 additions & 164 deletions

File tree

README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,9 @@ $ nettrace -h
136136
nettrace: a tool to trace skb in kernel and diagnose network problem
137137
138138
Usage:
139-
-s, --saddr filter source ip address
140-
--saddr6 filter source ip v6 address
141-
-d, --daddr filter dest ip address
142-
--daddr6 filter dest ip v6 address
143-
--addr filter source or dest ip address
144-
--addr6 filter source or dest ip v6 address
139+
-s, --saddr filter source ip/ipv6 address
140+
-d, --daddr filter dest ip/ipv6 address
141+
--addr filter source or dest ip/ipv6 address
145142
-S, --sport filter source TCP/UDP port
146143
-D, --dport filter dest TCP/UDP port
147144
-P, --port filter source or dest TCP/UDP port
@@ -165,7 +162,7 @@ Usage:
165162
-h, --help show help information
166163
```
167164
168-
其中,参数`s/d/addr/S/D/port/p/pid`用于进行报文的过滤,可以通过IP地址、端口、协议等属性进行过滤。其他参数的用途包括:
165+
其中,参数`s/d/addr/S/D/port/p/pid`用于进行报文的过滤,可以通过IP地址、端口、协议等属性进行过滤。其中,通过IPv6地址进行过滤目前也已经实现了支持。其他参数的用途包括:
169166
170167
- `t/trace`:要启用的跟踪模块,默认启用所有
171168
- `ret`:跟踪和显示内核函数的返回值

component/arg_parse.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <stdlib.h>
77
#define _LINUX_IN_H
88
#include <netinet/in.h>
9+
#include <arpa/inet.h>
910

1011
#include "arg_parse.h"
1112
#include "net_utils.h"
@@ -124,22 +125,33 @@ int parse_args(int argc, char *argv[], arg_config_t *config,
124125
break;
125126
}
126127
case OPTION_IPV4:
127-
if (ip2i(optarg, item->dest)) {
128+
if (!inet_pton(AF_INET, optarg, item->dest)) {
128129
printf("invalid ip address: %s\n", optarg);
129130
goto err;
130131
}
131132
S_SET(bool, true);
132133
break;
133134
case OPTION_IPV6:
134-
if (ipv6toi(optarg, item->dest)) {
135+
if (!inet_pton(AF_INET6, optarg, item->dest)) {
135136
printf("invalid ip address: %s\n", optarg);
136137
goto err;
137138
}
138139
S_SET(bool, true);
139140
break;
141+
case OPTION_IPV4ORIPV6:
142+
if (inet_pton(AF_INET, optarg, item->dest)) {
143+
S_SET(u16, ETH_P_IP);
144+
} else if (inet_pton(AF_INET6, optarg, item->dest)) {
145+
S_SET(u16, ETH_P_IPV6);
146+
} else {
147+
printf("invalid ip address: %s\n", optarg);
148+
goto err;
149+
}
150+
break;
140151
case OPTION_HELP:
141152
goto help;
142153
case OPTION_PROTO: {
154+
/* convert string to number in host order */
143155
int val, layer = proto2i(optarg, &val);
144156
if (!layer) {
145157
printf("protocol not found\n");

component/arg_parse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ enum option_type {
1616
OPTION_INT,
1717
OPTION_IPV4,
1818
OPTION_IPV6,
19+
OPTION_IPV4ORIPV6,
1920
OPTION_HELP,
2021
OPTION_BLANK,
2122
OPTION_PROTO,

component/net_utils.c

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static proto_item_t l4_protos[] = {
6565
{ "gre", 47 },
6666
{ "esp", 50 },
6767
{ "ah", 51 },
68+
{ "icmpv6", 58 },
6869
{ "mtp", 92 },
6970
{ "beetph", 94 },
7071
{ "encap", 98 },
@@ -91,6 +92,7 @@ char *l4_proto_names[] = {
9192
[46] = "RSVP",
9293
[47] = "GRE",
9394
[50] = "ESP",
95+
[58] = "ICMPV6",
9496
[51] = "AH",
9597
[92] = "MTP",
9698
[94] = "BEETPH",
@@ -146,39 +148,3 @@ int proto2i(char *proto, int *dest)
146148
return 4;
147149
return 0;
148150
}
149-
150-
void i2ipv6(char *dest, __u8 ip[])
151-
{
152-
int i = 0, offset = 0;
153-
154-
for (; i < 16; i += 2) {
155-
if (ip[i] || ip[i + 1])
156-
offset += sprintf(dest + offset, "%02x%02x:",
157-
ip[i], ip[i + 1]);
158-
else
159-
offset += sprintf(dest + offset, ":");
160-
}
161-
*(dest + offset - 1) = '\0';
162-
}
163-
164-
int ipv6toi(char *ip, __u8 *dest)
165-
{
166-
u16 *c = (u16 *)dest;
167-
u32 t[8] = {}, i = 0;
168-
169-
if (sscanf(ip, "%x:%x:%x:%x:%x:%x:%x:%x", t, t + 1, t + 2,
170-
t + 3, t + 4, t + 5, t + 6, t + 7) == 8)
171-
goto is_valid;
172-
173-
memset(t, 0, sizeof(t));
174-
if (sscanf(ip, "%x::%x:%x:%x:%x", t, t + 4, t + 5, t + 6,
175-
t + 7) == 5)
176-
goto is_valid;
177-
178-
return -1;
179-
180-
is_valid:
181-
for (i = 0; i < 8; i++)
182-
c[i] = htons(t[i]);
183-
return 0;
184-
}

component/net_utils.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,11 @@ typedef __u64 u64;
2727

2828
extern char *l4_proto_names[];
2929

30-
static inline void i2ip(char *dest, __u32 ip)
31-
{
32-
u8 *t = (u8 *)&ip;
33-
sprintf(dest, "%d.%d.%d.%d", t[0], t[1], t[2], t[3]);
34-
}
35-
36-
static inline int ip2i(char *ip, __u32 *dest)
37-
{
38-
u8 *c = (u8 *)dest;
39-
u32 t[4] = {};
40-
41-
if (sscanf(ip, "%u.%u.%u.%u", t, t + 1, t + 2, t + 3) != 4)
42-
return -EINVAL;
43-
44-
#define C(index) c[index] = t[index]
45-
C(0);
46-
C(1);
47-
C(2);
48-
C(3);
49-
#undef C
50-
return 0;
51-
}
52-
5330
static inline char *i2l4(u8 num)
5431
{
5532
return l4_proto_names[num];
5633
}
5734

5835
int proto2i(char *proto, int *dest);
59-
void i2ipv6(char *dest, u8 ip[]);
60-
int ipv6toi(char *ip, u8 *dest);
6136

6237
#endif

nodetrace/mark.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,10 @@ static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
3131

3232
static int parse_opts(int argc, char *argv[], bpf_args_t *args)
3333
{
34-
int proto_l;
35-
u16 proto;
34+
COMMON_PROG_ARGS_BEGIN()
3635

3736
option_item_t opts[] = {
38-
COMMON_PROG_ARGS(&args->pkt),
37+
COMMON_PROG_ARGS_DEFINE(&args->pkt),
3938
{ .type = OPTION_BLANK },
4039
{
4140
.sname = 'i', .dest = &nic, .type = OPTION_STRING,
@@ -54,11 +53,11 @@ static int parse_opts(int argc, char *argv[], bpf_args_t *args)
5453
.desc = "show help information",
5554
},
5655
};
57-
#undef E
58-
#undef R
5956

6057
if (parse_args(argc, argv, &prog_config, opts, ARRAY_SIZE(opts)))
6158
goto err;
59+
60+
COMMON_PROG_ARGS_END(&args->pkt)
6261
return 0;
6362
err:
6463
return -1;

script/bash-completion.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
complete -W '-s --saddr --saddr6 -d --daddr --daddr6 --addr --addr6 -p -D --dport -S --sport -P --port --pid -t --trace -v --detail --debug --bpf-debug --ret --basic --diag --diag-quiet --diag-keep --date --drop --drop-stack --hooks -h --help' nettrace
1+
complete -W '-s --saddr -d --daddr --addr -p -D --dport -S --sport -P --port --pid -t --trace -v --detail --debug --bpf-debug --ret --basic --diag --diag-quiet --diag-keep --date --drop --drop-stack --hooks -h --help' nettrace
22
complete -W '-h -s -d --addr -p --dport --sport --port -t -v --detail --stack --stack-tracer --timeline -c --ret --skb-mode --force-stack --tcp-flags -o --output' nettrace-legacy

shared/bpf/macro.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66

77
#define ETH_HLEN 14 /* Total octets in header. */
88

9+
#define IPPROTO_ICMPV6 58 /* ICMPv6 */
10+
11+
#define ICMPV6_ECHO_REQUEST 128
12+
#define ICMPV6_ECHO_REPLY 129
13+
14+
/* Codes for EXT_ECHO (PROBE) */
15+
#define ICMPV6_EXT_ECHO_REQUEST 160
16+
#define ICMPV6_EXT_ECHO_REPLY 161
17+
918
#define TC_ACT_UNSPEC (-1)
1019
#define TC_ACT_OK 0
1120
#define TC_ACT_RECLASSIFY 1

shared/bpf/skb_shared.h

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,30 +57,29 @@ typedef struct __attribute__((__packed__)) {
5757
#define TCP_FLAGS_RST (1 << 2)
5858
#define TCP_FLAGS_SYN (1 << 1)
5959

60+
#define APPLY_DEFINE_FIELD(dummy, a, b, ...) DEFINE_FIELD_##b
61+
#define DEFINE_FIELD_STD(type, name) \
62+
type name; \
63+
bool enable_##name;
64+
#define DEFINE_FIELD_ARRAY(type, name, size) \
65+
type name[size]; \
66+
bool enable_##name;
67+
#define DEFINE_FIELD(type, name, args...) \
68+
APPLY_DEFINE_FIELD(dummy, ##args, ARRAY, STD)(type, name, ##args)
69+
6070
/* used for packet filter condition */
6171
typedef struct {
62-
u32 saddr;
63-
bool enable_saddr;
64-
u32 daddr;
65-
bool enable_daddr;
66-
u32 addr;
67-
bool enable_addr;
68-
u8 saddr_v6[16];
69-
bool enable_saddr_v6;
70-
u8 daddr_v6[16];
71-
bool enable_daddr_v6;
72-
u8 addr_v6[16];
73-
bool enable_addr_v6;
74-
u16 sport;
75-
bool enable_sport;
76-
u16 dport;
77-
bool enable_dport;
78-
u16 port;
79-
bool enable_port;
80-
u16 l3_proto;
81-
bool enable_l3_proto;
82-
u8 l4_proto;
83-
bool enable_l4_proto;
72+
DEFINE_FIELD(u32, saddr)
73+
DEFINE_FIELD(u32, daddr)
74+
DEFINE_FIELD(u32, addr)
75+
DEFINE_FIELD(u8, saddr_v6, 16)
76+
DEFINE_FIELD(u8, daddr_v6, 16)
77+
DEFINE_FIELD(u8, addr_v6, 16)
78+
DEFINE_FIELD(u16, sport)
79+
DEFINE_FIELD(u16, dport)
80+
DEFINE_FIELD(u16, port)
81+
DEFINE_FIELD(u16, l3_proto)
82+
DEFINE_FIELD(u8, l4_proto)
8483
} pkt_args_t;
8584

8685
#define CONFIG_MAP_SIZE 1024

shared/bpf/skb_utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ static try_inline int probe_parse_ip(void *ip, parse_ctx_t *ctx)
274274
pkt->l4.udp.dport = dport;
275275
break;
276276
}
277+
case IPPROTO_ICMPV6:
277278
case IPPROTO_ICMP: {
278279
struct icmphdr *icmp = l4;
279280

@@ -285,7 +286,7 @@ static try_inline int probe_parse_ip(void *ip, parse_ctx_t *ctx)
285286
pkt->l4.icmp.id = _(icmp->un.echo.id);
286287
break;
287288
}
288-
case IPPROTO_ESP: {
289+
case IPPROTO_ESP: {
289290
struct ip_esp_hdr *esp_hdr = l4;
290291
if (ATTR_ENABLE(port))
291292
goto err;

0 commit comments

Comments
 (0)