Skip to content

Commit b93a82c

Browse files
rjarrychristophefontaine
authored andcommitted
icmp: require clients to provide ping identifier
Always require the clients to provide an ICMP identifier AND sequence number like in the IPv6 implementation. Signed-off-by: Robin Jarry <[email protected]>
1 parent acf673e commit b93a82c

File tree

3 files changed

+18
-34
lines changed

3 files changed

+18
-34
lines changed

modules/ip/api/gr_ip4.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,18 @@ struct gr_ip4_addr_list_resp {
139139
struct gr_ip4_icmp_send_req {
140140
ip4_addr_t addr;
141141
uint16_t vrf;
142+
uint16_t ident;
142143
uint16_t seq_num;
143144
uint8_t ttl;
144145
};
145146

146-
struct gr_ip4_icmp_send_resp {
147-
uint16_t ident;
148-
};
147+
// struct gr_ip4_icmp_send_resp { };
149148

150149
#define GR_IP4_ICMP_RECV REQUEST_TYPE(GR_IP4_MODULE, 0x0025)
151150

152151
struct gr_ip4_icmp_recv_req {
153152
uint16_t ident;
153+
uint16_t seq_num;
154154
};
155155

156156
struct gr_ip4_icmp_recv_resp {

modules/ip/cli/icmp.c

+6-7
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,26 @@ static cmd_status_t icmp_send(
3737
) {
3838
struct gr_ip4_icmp_recv_resp *reply_resp;
3939
struct gr_ip4_icmp_recv_req reply_req;
40-
struct gr_ip4_icmp_send_resp *start_resp;
4140
int timeout, ret, errors;
4241
void *resp_ptr = NULL;
42+
uint16_t ping_id;
4343

4444
stop = false;
4545
errors = 0;
4646
errno = 0;
47+
ping_id = random();
4748

4849
for (int i = mode_traceroute; i < count && stop == false; i++) {
4950
req->ttl = mode_traceroute ? i : 64;
51+
req->ident = ping_id;
5052
req->seq_num = i;
5153

52-
ret = gr_api_client_send_recv(c, GR_IP4_ICMP_SEND, sizeof(*req), req, &resp_ptr);
54+
ret = gr_api_client_send_recv(c, GR_IP4_ICMP_SEND, sizeof(*req), req, NULL);
5355
if (ret < 0)
5456
return CMD_ERROR;
5557

56-
start_resp = resp_ptr;
57-
reply_req.ident = start_resp->ident;
58-
free(resp_ptr);
59-
resp_ptr = NULL;
60-
58+
reply_req.ident = ping_id;
59+
reply_req.seq_num = i;
6160
timeout = 50;
6261
do {
6362
usleep(10000);

modules/ip/control/icmp.c

+9-24
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <gr_module.h>
1212
#include <gr_queue.h>
1313

14-
#include <rte_atomic.h>
1514
#include <rte_icmp.h>
1615
#include <rte_ip.h>
1716
#include <rte_ring.h>
@@ -49,7 +48,7 @@ static void icmp_input_cb(struct rte_mbuf *m) {
4948

5049
// Search for the oldest ICMP response matching the given identifier.
5150
// If found, the packet is removed from the queue.
52-
static struct rte_mbuf *get_icmp_response(uint16_t ident) {
51+
static struct rte_mbuf *get_icmp_response(uint16_t ident, uint16_t seq_num) {
5352
struct icmp_queue_item *i, *tmp;
5453
struct rte_mbuf *mbuf = NULL;
5554

@@ -78,7 +77,8 @@ static struct rte_mbuf *get_icmp_response(uint16_t ident) {
7877
}
7978
}
8079

81-
if (rte_be_to_cpu_16(icmp->icmp_ident) == ident) {
80+
if (rte_be_to_cpu_16(icmp->icmp_ident) == ident
81+
&& rte_be_to_cpu_16(icmp->icmp_seq_nb) == seq_num) {
8282
mbuf = i->mbuf;
8383
icmp_queue_pop(i, false);
8484
break;
@@ -88,33 +88,18 @@ static struct rte_mbuf *get_icmp_response(uint16_t ident) {
8888
return mbuf;
8989
}
9090

91-
// Global id which is used to differentiate between api clients
92-
static rte_atomic16_t icmp_ident = RTE_ATOMIC16_INIT(0);
93-
94-
static struct api_out icmp_send(const void *request, void **response) {
91+
static struct api_out icmp_send(const void *request, void ** /*response*/) {
9592
const struct gr_ip4_icmp_send_req *req = request;
96-
struct gr_ip4_icmp_send_resp *resp = NULL;
9793
const struct nexthop *nh;
98-
int ret;
99-
100-
if ((resp = calloc(1, sizeof(*resp))) == NULL)
101-
return api_out(ENOMEM, 0);
94+
int ret = 0;
10295

10396
if ((nh = rib4_lookup(req->vrf, req->addr)) == NULL) {
10497
ret = -errno;
105-
goto fail;
98+
goto out;
10699
}
107100

108-
resp->ident = rte_atomic16_add_return(&icmp_ident, 1);
109-
ret = icmp_local_send(req->vrf, req->addr, nh, resp->ident, req->seq_num, req->ttl);
110-
if (ret < 0)
111-
goto fail;
112-
113-
*response = resp;
114-
115-
return api_out(0, sizeof(*resp));
116-
fail:
117-
free(resp);
101+
ret = icmp_local_send(req->vrf, req->addr, nh, req->ident, req->seq_num, req->ttl);
102+
out:
118103
return api_out(-ret, 0);
119104
}
120105

@@ -128,7 +113,7 @@ static struct api_out icmp_recv(const void *request, void **response) {
128113
size_t len = 0;
129114
int ret = 0;
130115

131-
m = get_icmp_response(icmp_req->ident);
116+
m = get_icmp_response(icmp_req->ident, icmp_req->seq_num);
132117
if (m == NULL)
133118
return api_out(0, 0);
134119

0 commit comments

Comments
 (0)