Skip to content

Commit

Permalink
ip: send an icmp message when TTL is expired
Browse files Browse the repository at this point in the history
Instead of dropping silently the packet, forge and send
back an ICMP message "Time To live exceeded".

Signed-off-by: Christophe Fontaine <cfontain@redhat.com>
  • Loading branch information
christophefontaine authored and rjarry committed Jul 2, 2024
1 parent 7170e16 commit 350afcd
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 3 deletions.
8 changes: 7 additions & 1 deletion modules/ip/datapath/gr_ip4_datapath.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef _GR_IP4_DATAPATH_H
#define _GR_IP4_DATAPATH_H

#include <gr_iface.h>
#include <gr_ip4_control.h>
#include <gr_mbuf.h>
#include <gr_net_types.h>
Expand All @@ -14,7 +15,10 @@

#include <stdint.h>

GR_MBUF_PRIV_DATA_TYPE(ip_output_mbuf_data, { struct nexthop *nh; });
GR_MBUF_PRIV_DATA_TYPE(ip_output_mbuf_data, {
struct nexthop *nh;
const struct iface *input_iface;
});

GR_MBUF_PRIV_DATA_TYPE(arp_mbuf_data, {
struct nexthop *local;
Expand Down Expand Up @@ -50,4 +54,6 @@ static inline void ip_set_fields(struct rte_ipv4_hdr *ip, struct ip_local_mbuf_d
ip->hdr_checksum = rte_ipv4_cksum(ip);
}

#define GR_IP_ICMP_TTL_EXCEEDED 11

#endif
2 changes: 0 additions & 2 deletions modules/ip/datapath/ip_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,3 @@ static struct gr_node_info info = {
};

GR_NODE_REGISTER(info);

GR_DROP_REGISTER(ip_forward_ttl_exceeded);
81 changes: 81 additions & 0 deletions modules/ip/datapath/ip_forward_ttl_exceeded.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2024 Christophe Fontaine

#include <gr_datapath.h>
#include <gr_graph.h>
#include <gr_ip4_control.h>
#include <gr_ip4_datapath.h>
#include <gr_log.h>
#include <gr_mbuf.h>

#include <rte_common.h>
#include <rte_graph_worker.h>
#include <rte_icmp.h>
#include <rte_ip.h>

enum edges {
ICMP_OUTPUT = 0,
EDGE_COUNT,
};

static uint16_t ip_forward_ttl_exceeded(
struct rte_graph *graph,
struct rte_node *node,
void **objs,
uint16_t nb_objs
) {
struct ip_local_mbuf_data *ip_data;
const struct iface *input_iface;
struct rte_icmp_hdr *icmp;
struct rte_ipv4_hdr *ip;
struct rte_mbuf *mbuf;
uint16_t vrf_id;

for (uint16_t i = 0; i < nb_objs; i++) {
mbuf = objs[i];

ip = rte_pktmbuf_mtod(mbuf, struct rte_ipv4_hdr *);
// No need to check headroom
icmp = (struct rte_icmp_hdr *)
rte_pktmbuf_prepend(mbuf, sizeof(struct rte_icmp_hdr));

// Get the local router IP address from the input iface
input_iface = ip_output_mbuf_data(mbuf)->input_iface;
vrf_id = input_iface->vrf_id;
ip4_addr_t local_ip = ip4_addr_get(input_iface->id)->ip;

ip_data = ip_local_mbuf_data(mbuf);
ip_data->vrf_id = vrf_id;
ip_data->src = local_ip;
ip_data->dst = ip->src_addr;

// RFC792 payload size: ip header + 64 bits of original datagram
ip_data->len = sizeof(struct rte_icmp_hdr) + rte_ipv4_hdr_len(ip) + 8;
ip_data->proto = IPPROTO_ICMP;

icmp->icmp_type = GR_IP_ICMP_TTL_EXCEEDED;
icmp->icmp_code = 0; // time to live exceeded in transit
icmp->icmp_cksum = 0;
icmp->icmp_ident = 0;
icmp->icmp_seq_nb = 0;

rte_node_enqueue_x1(graph, node, ICMP_OUTPUT, mbuf);
}

return nb_objs;
}

struct rte_node_register ip_forward_ttl_exceeded_node = {
.name = "ip_forward_ttl_exceeded",
.process = ip_forward_ttl_exceeded,
.nb_edges = EDGE_COUNT,
.next_nodes = {
[ICMP_OUTPUT] = "icmp_output",
},
};

static struct gr_node_info info = {
.node = &ip_forward_ttl_exceeded_node,
};

GR_NODE_REGISTER(info);
1 change: 1 addition & 0 deletions modules/ip/datapath/ip_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ ip_input_process(struct rte_graph *graph, struct rte_node *node, void **objs, ui
next = FORWARD;
// Store the resolved next hop for ip_output to avoid a second route lookup.
ip_output_mbuf_data(mbuf)->nh = nh;
ip_output_mbuf_data(mbuf)->input_iface = iface;
next_packet:
rte_node_enqueue_x1(graph, node, next, mbuf);
}
Expand Down
1 change: 1 addition & 0 deletions modules/ip/datapath/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ src += files(
'icmp_input.c',
'icmp_output.c',
'ip_forward.c',
'ip_forward_ttl_exceeded.c',
'ip_input.c',
'ip_local.c',
'ip_output.c',
Expand Down

0 comments on commit 350afcd

Please sign in to comment.