TCPIP Stack Dev PartA
TCPIP Stack Dev PartA
TCP/IP Stack
Application
Transport Layer
Implement in C :
Network Layer
ARP
Data link layer
Layer 2 Routing Complete
Layer 3 routing
ICMP, Ping , Trace-Route
Vlan Based Routing - All In one Project !!
I would like to thanks some prominent personalities who encouraged me to develop this project.
The Motive is to develop a framework which could be used to try And test Networking Solutions
5. Working with Git – Very important Codes written in assignment shall be used in the project
6. Compilation, Makefile
➢ Nobody is Stopping you to implement VLAN functionality
➢ Unlimited Scope !
➢ You shall be implementing all logic to parse the packet content, and take decision what to do with the packet
➢ We shall be building up the topology where nodes would represent Layer3 routers and/or L2 switch or Hub. In other words,
we shall be writing simplified code for L2 switching and L3 routing
➢ You don’t need multiple machines, all shall be done on one machine, within our project !
➢ Take Away :
➢ You shall have low level thorough knowledge of TCP/IP Stack functioning
➢ Learn how to parse the packet, evaluate packet hdr content, and take action accordingly
➢ A Strong candidature and portfolio to join Networking development roles Or otherwise
➢ Open ended Project – You can grow old working on this project, but this project wont end
Application
Developing Transport Layer
Sign up Here to get Free 30 days trial access to all our courses
[Link]
Generic Graph Construction
➢ First, We shall develop a library using which we can create static graph
➢ As of now, graph nodes are simple nodes, they shall not represent routing devices
➢ Files to be created :
graph.h , graph.c, testapp.c
node_t
eth0/0 eth0/1
R0 R1
➢ A graph is a collection of nodes link_t
eth0/4 eth0/2
➢ An interface has a : interface_t
➢ Name
➢ Owning node
➢ A wire (or link)
eth0/5 eth0/3
R2
➢ A link is defined as pair of interfaces Tip : Try to model Data structure
Such that it depicts the
➢ A node has a : Organization of information
➢ Name In real physical world
➢ Set of empty interface slots
Generic Graph Construction
➢ Files to be created :
graph.h , graph.c, testapp.c
node_t
eth0/0 eth0/1
R0 R1
➢ Public APIs link_t
eth0/4 eth0/2
graph_t *create_new_graph(char *topology_name); interface_t
eth0/5 eth0/3
void insert_link_between_two_nodes (node_t *node1,
R2
node_t *node2,
char *from_if_name,
char *to_if_name,
unsigned int cost);
Display Routines :
void dump_graph (graph_t *graph);
[Link]
➢ Every interface MUST have mac address, and MAY have ip-address/mask
Setting up Network Topology
➢ Public APIs
Declare in net.h, define in net.c , use in testapp.c
[Link]/24
➢ As soon, as you add a link to the topology connecting two nodes, the end eth0/5 eth0/3
Interfaces must be assigned some auto generated mac addresses R2
[Link]
Mac_address generated = fn (node_name, interface_name, some heuristics )
Display function – Display the entire network topology with networking properties also
void dump_nw_graph(graph_t *graph);
Setting up Network Topology
➢ Display function – Display the entire network topology with networking properties also
net.h/net.c
[Link] [Link]
void dump_nw_graph(graph_t *graph);
eth0/0 eth0/1
R0 R1
eth0/4 eth0/2
➢ As we progress into the course, we shall need to add more networking [Link]/24
properties to the nodes and interfaces. We shall be defining more new
members to node_nw_prop_t and intf_nw_props_t structures accordingly
[Link]/24
eth0/5 eth0/3
R2
[Link]
Application
Developing Transport Layer
➢ We shall be needing an external CLI library using which we can implement our own customize show, config, clear commands
➢ We shall be using the CLI to reconfigure our network topology, display information etc
➢ Pre-requisite :
➢ You need to do the 80-minute course (Link to the course in Resource Section)
to understand how to use CLI library, then comeback !
Pls do assignments in the course to get a hands-on the libcli library
➢ You can use this CLI library in future for your other C/C++ projects
➢ Once you come back, we shall be implementing Demo commands to our project using CLI library
CLI Integration
➢ Verify Compilation
➢ Commit
CLI Integration
➢ Implement Commands :
➢ show topology
Files to be modified :
nwcli.c
cmdcodes.h
testapp.c
Application
Developing Transport Layer
➢ Now that our network graph are fully setup, and we can also interact with our Routing Devices using CLI . . .
➢ It’s a time to setup the framework using which Nodes can exchange data/packets with direct peers
R0 R1
R2
I1 I2
Logical View : R0 R1
[Link], 40002
[Link], 40002
Data (echoed back !)
Data
Linux OS
Packet Exchange Simulation Infra Setup
I1 I2
Logical View : R0 R1
Linux OS
Packet Exchange Simulation Infra Setup
I1 I2
Logical View : R0 R1
1. Opening Sockets : Our application assigns unique UDP port number to each node of the topology
2. Opening Sockets : Our application opens a UDP socket for all port numbers,
init_udp_socket (node_t *node)
4. Packet Transmission : Nodes Communicate by sending data to destination Node’s port number with
ip = [Link] I1 I2
R0 R1
send_pkt_out(char *pkt, unsigned int pkt_size, interface_t *oif)
6. Packet Reception : Based on Dst port number in the echoed data received by our application, our
application handover the data to the destination node
_network_start_pkt_receiver_thread(void *arg)
7. Auxiliary Information : Using Auxiliary information, Recipient interface name can be known
_pkt_receive(node_t *receving_node, char *pkt_with_aux_data, unsigned int pkt_size)
8. Final Packet Reception : Actual packet (without auxiliary data) is received by the recipient node on an IIF.
pkt_receive ((node_t *node, interface_t *interface, char *pkt, unsigned int pkt_size)
I1 I2
R0 R1
7. Layer 3
➢ Route Installation ➢ We shall be cooking up the packets :
➢ L3 Routing ➢ Attaching and removing headers
➢ Modifying headers
➢ Copying packet contents
8. Application ➢ Any error -> Memory corruption !!
➢ Ping
➢ Traceroute
➢ Do all assignments
9. Supporting VLANs
➢ Access Ports
➢ Trunk Ports
Implementing ARP
Goal
➢ Any interface of a Routing Device (L3 Router Or L2 Switch) can operate in either of two modes at any given time :
➢ L3 Mode
➢ L2 Mode
eth0/1
Interface Operating modes trunk
eth0/2
eth0/4
D [Link]/24
access
➢ A Routing device by itself is not L2 switch or L3 Router, it is called L3 Router or L2 switch in respect of its interface
configuration
Defining Ethernet header
File : Layer2/layer2.h
eth0/4
D
➢ Whenever a Routing Device receives a packet on its local interface , the first thing it has to decide is whether it should
process the incoming packet or reject it right away before packet could even enter into TCP/IP Stack.
➢ Acceptance or Rejection of the packet depends on many factors including but not limited to :
Interface Operating Modes
Interface Configuration
Packet Contents
➢ If the packet is Accepted, Routing device handover the packet to TCP/IP stack , and the ingress journey of the packet
commences
Packet Processing Criteria
API : Layer2/layer2.h
Now, we are in a position to write an API which decides whether routing device should accept Or reject the incoming
packet arrived on an interface operating in L3 mode:
Pseudocode :
➢ IF interface is operating in L3 mode and dst mac in ethernet hdr == IF_MAC(interface) -> Return TRUE
➢ IF interface is operating in L3 mode and dst mac in ethernet hdr is BROADCAST MAC -> Return TRUE
Pseudocode :
➢ IF interface is operating in ACCESS (or TRUNK) mode -> Return TRUE (later)
➢ IF interface is operating in L3 mode and dst mac in ethernet hdr == IF_MAC(interface) -> Return TRUE
➢ IF interface is operating in L3 mode and dst mac in ethernet hdr is BROADCAST MAC -> Return TRUE
➢ Before We write out first line of code to send and receive packets/frames between
our virtual routing devices, we need to get familiar with the packet buffers
– a Memory used to store the pkt/frame generated by the source layer of TCP/IP Stack
Packet Buffer Management -> Source Layers of TCP/IP Stack
application The Layers of the TCP/IP Stack which generates the data to be processed
by the TCP/IP Stack are called as Source Layers
Transport
“Source” – source of data
Network
Application and Physical Layer are Source Layers of TCP/IP Stack !
Physical Layer : Converts the electrical signals on wire into Data, and feed into TCP/IP Stack
Data Link From BOTTOM
Application Layer : Software Program which generates the data and feeds it into TCP/IP Stack
Physical From TOP
Packet Buffer Management -> Ingress Journey
Transport
How are you We Simply increment the “pkt” pointer
Transport Hdr Application data
to chop off the header from the packet
while delivering it to the next higher
Network How are you Layer in the TCP/IP Stack
Network Hdr Transport Hdr Application data
Physical
1000101010000101 … .. 01010… . . . .101010101000110
Physical link/wire
Packet Buffer Management -> Egress Journey
Physical
1000101010000101 … .. 01010… . . . .101010101000110
Physical link/wire
➢ Whenever a Node receive a frame on its local interface from nbr node, The API pkt_receive (. . . ) is invoked.
char *
net.c/.h pkt_buffer_shift_right(char *pkt, unsigned int pkt_size,
unsigned int total_buffer_size);
➢ You have to be extremely careful while dealing with packet buffers, manipulating packet contents,
modifying the packet headers etc
➢ Preventive Measures :
➢ Use Debuggers such as gdb
➢ Use as many printfs as you want
➢ Be sure what you are doing !
Implementing ARP -> Data Structures
hw_type = 1 proto_type = 0x0800 hw_addr_len = 6 proto_addr_len = 4 short hw_type; /*1 for ethernet cable*/
Opcode = 1 Or 2 Src MAC Src IP Dst Mac Dst IP
arp_hdr_t
ARP Broadcast
Request Message
ethernet_hdr_t
Implementing ARP -> Data Structures
arp_hdr_t
ARP Reply Message
ethernet_hdr_t
Implementing ARP -> ARP Table -> Data Structures
➢ Host/L3 Routers maintain a table called ARP table which contain ARP entries Layer2/layer2.h
glthread_t arp_entries;
} arp_table_t;
Initialize the ARP table, should be called when a node is created during topology creation i.e. from init_node_nw_prop(. . . )
Dump API :
void
send_arp_broadcast_request (node_t *node, [Link]/24 [Link]/24
H1 H2
interface_t *oif, eth0/1 eth0/2
char *ip_addr);
➢ nwcli.c
➢ Backend handler :
static int
arp_handler (param_t *param, ser_buff_t *tlv_buf,
op_mode enable_or_disable);
CLI to dump ARP table of a node Next, we shall discuss the ARP Cycle …
➢ nwcli.c
➢ Backend handler :
static int
show_arp_handler (param_t *param, ser_buff_t *tlv_buf,
op_mode enable_or_disable);
Implementing ARP -> ARP Cycle
layer2.h/layer2.c
[Link]/24 [Link]/24
H1 eth0/2 H2
eth0/1
void
send_arp_broadcast_request (node_t *node,
interface_t *oif, ARP Broadcast
char *ip_addr);
static void
process_arp_broadcast_request (node_t *node,
in
ethernet_hdr_t *ether
static void
send_arp_reply_msg (ethernet_hdr_t *ethernet_hdr_in,
interface_t *oif)
ARP Reply
static void
process_arp_reply_msg(node_t *node, interface_t *iif,
ethernet_hdr_t *ethernet_hdr); << Made an entry into ARP table !!
Implementing ARP -> ARP Msg Processing by the Routing Device
layer2_frame_recv (. . .) /*Pre-Entry point of frame into the TCP/IP Stack, but not yet entered !*/
(Standing outside the door, knocking … !)
➢ Next :
➢ Let us implement L2 switching and MAC based forwarding
L2 Switching Implementation
Goal
[Link]/24
We shall implement L2 Switch based functionality in Two phases :
eth0/4
eth0/6
[Link]/24
eth0/3
H3
L2 Switching Implementation
➢ If some interfaces of routing device are operating in L3 mode ( ip-address configured ), and some are in ACCESS/TRUNK
mode, then node is behaving as Router as well as L2switch
➢ A Node by itself is not L2 switch or Router, it is called Router or L2 switch in respect of its interface configuration
eth0/2
D [Link]/24 This Device is L2 Switch wrt to interfaces
eth0/1, eth0/4
eth0/6
L3 L2
IP Address ACESS Or TRUNK
net.h
typedef enum{
New APIs : Layer2/layer2.h, layer2.c ACCESS,
TRUNK,
void L2_MODE_UNKNOWN
node_set_intf_l2_mode (node_t *node, char *intf_name, } intf_l2_mode_t;
intf_l2_mode_t
typedef struct intf_nw_props_ {
intf_l2_mode); ...
• Interface cannot operate in L3 and L2 mode at the same time intf_l2_mode_t intf_l2_mode;
• Interface cannot operate in ACCESS and TRUNK mode at the same time ...
• Write Robust API to handle all scenarios } intf_nw_props_t;
• Enhance existing show topology command to show interface mode of operation
• Config CLI : config node <node-name> interface < intf-name > l2mode < access|trunk >
L2 Switching Implementation
graph_t * [Link]
build_simple_l2_switch_topo();
H4
[Link]/24
eth0/7
eth0/1
[Link]/24 [Link]/24
[Link] H1 L2 Switch H3 [Link]
eth0/5 eth0/4 eth0/2 eth0/6
eth0/3
[Link]/24
eth0/8
H2
[Link]
L2 Switching Implementation -> Phase 1 -> Setting Up MAC tables
➢ Just like we added ARP table to each Router/Host, we need to add mac table to each L2 Switch
Layer2/l2switch.c
glthread_t mac_entries;
} mac_table_t;
L2 Switching Implementation -> Phase 1 -> Setting Up MAC tables -> Mac Table APIs
D - void
delete_mac_table_entry (mac_table_t *mac_table, char *mac);
Dumping API:
Layer2/l2switch.c
Initialize : void
dump_mac_table(mac_table_t *mac_table);
void
init_mac_table(mac_table_t **mac_table);
L2 Switching Implementation -> Phase 2 -> L2 Switch Mac Learning and Forwarding
[Link]/24
Eth_hdr eth0/7
IF_MAC IF_MAC
(eth0/5) (eth0/6) eth0/4
[Link]/24 [Link]/24
H1 L2 Switch H2 [Link]
eth0/5 eth0/3 eth0/1 eth0/6
[Link]
eth0/2
MAC OIF
[Link]/24
eth0/8
IF_MAC(eth0/5) eth0/3
H3
[Link]
L2 Switching Implementation -> Phase 2 -> L2 Switch Mac Learning and Forwarding
[Link]/24
eth0/7
Eth_hdr
IF_MAC IF_MAC
eth0/4 (eth0/5) (eth0/6)
[Link]/24 [Link]/24
H1 L2 Switch H2 [Link]
eth0/5 eth0/3 eth0/1 eth0/6
[Link]
eth0/2
MAC OIF
[Link]/24
eth0/8
IF_MAC(eth0/5) eth0/3
H3
IF_MAC(eth0/6) eth0/1
[Link]
L2 Switching Implementation -> Phase 2 -> L2 Switch Mac Learning and Forwarding
eth0/4
[Link]/24 [Link]/24
H1 L2 Switch H2 [Link]
eth0/5 eth0/3 eth0/1 eth0/6
[Link]
eth0/2
MAC OIF
[Link]/24
eth0/8 IF_MAC(eth0/5) eth0/3
H3
IF_MAC(eth0/6) eth0/1
IF_MAC(eth0/7) eth0/4
[Link]
layer2_frame_recv (. . .) /*Pre-Entry point of frame into the TCP/IP Stack, but not yet entered !*/
(Standing outside the door, knocking … !)
Layer2/l2switch.c
void
l2_switch_recv_frame ( interface_t *interface,
char *pkt, unsigned int pkt_size) {
l2_switch_perform_mac_learning(..)
l2_switch_forward_frame(..)
}
➢ Pre-requisite :
➢ Understand concepts of VLANs
➢ Understand 802.1q Header format
➢ Vlan Tagging and Un-tagging of ethernet Hdr frames
➢ I will discuss theory in fast pace as required to discuss our implementation of codes
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging
➢ Vlan Aware L2 Switches performs Vlan tagging or un-tagging on frames which they receive and process
➢ To start with, we shall discuss the implementation of APIs responsible to tag or un-tag the frames with a
given VLAN ID.
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging
802.1q vlan
Dest Address(6) Src Address(6) Type (2) Info [46 - 1500] FCS (4)
tagging
802.1q vlan
vlan_ethernet_hdr_t -> Dest Address(6) Src Address(6)
tagging
Type (2) Info [46 - 1500] FCS (4)
TPID
0x8100
PRI CFI Vlan ID <- vlan_8021q_hdr_t
2B 3b 1b 12b
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging -> Tagged Ethernet Header
802.1q vlan
vlan_ethernet_hdr_t -> Dest Address(6) Src Address(6)
tagging
Type (2) Info [46 - 1500] FCS (4)
➢ Throughout our code, we shall represent the ethernet hdr of the frame with default structure
ethernet_hdt_t, though it could be tagged or not
➢ Once it is confirmed that the frame is tagged, we shall typecast ethernet_hdr_t into
vlan_ethernet_hdr_t
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging -> Tagged Ethernet Header
For Example :
ethernet_hdr_t *frame; /*Given*/
802.1q vlan
vlan_ethernet_hdr_t -> Dest Address(6) Src Address(6)
tagging
Type (2) Info [46 - 1500] FCS (4)
802.1q vlan
vlan_ethernet_hdr_t -> Dest Address(6) Src Address(6)
tagging
Type (2) Info [46 - 1500] FCS (4)
802.1q vlan
vlan_ethernet_hdr_t -> Dest Address(6) Src Address(6)
tagging
Type (2) Info [46 - 1500] FCS (4)
Do the Assignment !!
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging -> APIs
➢ In VLAN Based L2 Switching, L2 switches would need to convert tagged frames into untagged ones
and vice versa as frame are L2 switched
➢ Assume that the frame is already “right shifted” and packet buffer has ample of space to the left of frame bits
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging -> APIs
ethernet_hdr_t ->
Layer2/layer2.c/layer2.h
ethernet_hdr_t *
untag_pkt_with_vlan_id(ethernet_hdr_t *ethernet_hdr,
unsigned int total_pkt_size,
unsigned int *new_pkt_size);
802.1q vlan
Dest Address(6) Src Address(6) Type (2) Info [46 - 1500] FCS (4)
tagging
vlan_ethernet_hdr_t ->
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging -> APIs
ethernet_hdr_t ->
Layer2/layer2.c/layer2.h
ethernet_hdr_t *
tag_pkt_with_vlan_id(ethernet_hdr_t *ethernet_hdr,
unsigned int total_pkt_size,
int vlan_id,
unsigned int *new_pkt_size);
802.1q vlan
Dest Address(6) Src Address(6) Type (2) Info [46 - 1500] FCS (4)
tagging
vlan_ethernet_hdr_t ->
L2 Switching Implementation -> VLAN Support -> Vlan Tagging and Untagging -> APIs
Input -> Available space Dst MAC Src MAC Type Payload FCS
Step 1 : Copy into temp memory Dst MAC Src MAC Type
Step 2 : Create Room of size = sizeof (vlan_8021q_hdr_t)
Create room Dst MAC Src MAC Type Payload FCS
Step 6 : Free the temp memory if allocated on Heap and Return updated new frame header pointer
L2 Switching Implementation -> Interface Vlan member ship
L3 Mode
L2 Mode
IP Address
ACCESS TRUNK
Atmost 1 VLAN Atleast 1 VLAN
• If interface is operating in ACCESS mode, then only vlan[0] MAY be set to vlan no
• If interface is operating in VLAN mode, then vlan[ ] can contain upto MAX_VLAN_MEMBERSHIP vlan IDs
APIs : Layer2/layer2.c
void
node_set_intf_l2_mode (node_t *node, char *intf_name,
intf_l2_mode_t intf_l2_mode);
void
node_set_intf_vlan_membsership( node_t *node,
char *intf_name,
unsigned int vlan_id);
L2 Switching Implementation -> Interface Vlan member ship -> Data Structures
L2 Switching Implementation -> Interface Vlan member ship -> Data Structures
CLI :
To set interface mode :
config node <node-name> interface <if-name> l2mode <l2-mode-val>
L2 Switch
(Mac Learning
and Mac fwding oif
iif Algorithm)
L2 Switching Implementation -> VLAN Support -> Frame Ingress
Case # Interface Operation L2 mode Type Pkt Vlan tag Interface vlan id Action
mode (Access or Trunk)
1 L3 mode - No - If intf mac == Dst mac Or Dst
mac is Broadcast mac then
Accept, else reject
➢ Once the L2 Switch Accepts the frame, it needs to forward the frame out of other L2 interfaces as by dictated by
matching mac table entry
layer2_frame_recv(. . .)
Frame Ingress
l2_frame_recv_qualify_on_interface(. . .)
l2_switch_recv_frame(. . .)
l2_switch_forward_frame (. . .)
L2 Switching Implementation -> VLAN Support -> Frame Egress
➢ Once the L2 Switch Accepts the frame, it needs to forward the frame out of other L2 interfaces as by dictated by
matching mac table entry
layer2_frame_recv(. . .)
Frame Ingress
l2_frame_recv_qualify_on_interface(. . .)
l2_switch_recv_frame(. . .)
l2_switch_forward_frame (. . .)
send_pkt_out(. . .)
/*Finally send the frame out of a device*/
L2 Switching Implementation -> VLAN Support -> Frame Egress
➢ We shall write an API specific to L2 switch, which checks all conditions before it decide to finally send the frame out of a
L2 interface of a switch
Layer2/l2switch.c
static bool_t
l2_switch_send_pkt_out (char *pkt,
unsigned int pkt_size,
interface_t *oif)
L2 Switch
(Frame F) OIF
L2 Switching Implementation -> VLAN Support -> Frame Egress
API : l2_switch_send_pkt_out (. . .)
Layer2/l2switch.c
eth0/1
L2 Switch
Dst Src VLAN ID =
MAC MAC X
Case # Interface Operation L2 mode Type Pkt Vlan tag Interface vlan id Action
mode (Access or Trunk)
0 L3 Mode - Don’t matter - Assert
Correction
1 L2 Mode ACCESS No Not enabled Assert
void
l2_switch_forward_frame ( node_t *node, interface_t *recv_intf,
ethernet_hdr_t *ethernet_hdr,
unsigned int pkt_size);
Must Use :
l2_switch_flood_pkt_out(. . .) &
l2_switch_send_pkt_out(. . .)
L2 Switching Implementation -> VLAN Support -> L2 Loops
eth0/11
AC, V10 eth0/1, TR, V10 eth0/12
L2 Switch1 L2 Switch2 AC, V10 [Link]/24
[Link]/24
eth0/2, TR, V10
END
L3 Routing Implementation
Goal
[Link]/24 [Link]/24
R0
eth0/4 eth0/0
Lo: [Link] ➢ Pre-requisites :
➢ Understand L3 routing
[Link]/24 [Link]/24 ➢ Understanding L3 Routing Table
eth0/5 eth0/1 ➢ Longest Prefix Match
[Link]/24 [Link]/24 ➢ Local and Remote subnets
R2 R1
eth0/3 eth0/2 ➢ Loopback Addresses
Lo: [Link] Lo: [Link]
L3 Routing Implementation
Goal
[Link]/24 [Link]/24
R0
eth0/4 eth0/0 ➢ All nodes in the topology are L3 routers
Lo: [Link]
➢ Router’s must have L3 routes to reach IP-addresses
[Link]/24 [Link]/24 falling in remote subnets
eth0/5 eth0/1
[Link]/24 [Link]/24 ➢ All Routers and Hosts must have L3 routing Table
R2 eth0/2 R1
eth0/3
Lo: [Link] Lo: [Link] ➢ We shall implement L3 routing logic
[Link] 32 TRUE - -
typedef struct rt_table_{
[Link] 24 TRUE - -
[Link] 24 FALSE [Link] eth0/0
glthread_t route_list;
[Link] 32 FALSE [Link] eth0/0
} rt_table_t;
[Link] 32 FALSE [Link] eth0/4
[Link] 24 TRUE - -
L3 Routing Implementation -> Phase 1 Data structure Setup
void void
init_rt_table (rt_table_t **rt_table); rt_table_add_route (rt_table_t *rt_table,
char *dst, char mask,
void char *gw, char *oif);
rt_table_add_direct_route (rt_table_t *rt_table,
char *dst, char mask);
l3_route_t *
void l3rib_lookup_lpm(rt_table_t *rt_table,
dump_rt_table (rt_table_t *rt_table); uint32_t dest_ip);
L3 Routing Implementation -> Phase 1 Data structure Setup
...
init_rt_table(&(node_nw_prop->rt_table));
...
}
L3 Routing Implementation -> Phase 2 L3 Route Installation
[Link]/24
R0 [Link]/24 We need to Install L3 routes in L3 routers/Hosts
eth0/4 eth0/0 So that they can forward the traffic
Lo: [Link]
CLI :
[Link]/24 [Link]/24 config node <node-name> route <dest> <mask>
eth0/5 eth0/1 <gw-ip> <oif-name>
[Link]/24 [Link]/24
R2 eth0/2 R1
eth0/3
Lo: [Link] Lo: [Link] Back-end handler :
RT for R0
Dest Mask Is_direct Gw_ip oif static int
[Link] 32 TRUE - -
l3_config_handler(param_t *param,
[Link] 24 TRUE - -
ser_buff_t *tlv_buf,
[Link] 24 FALSE [Link] eth0/0
op_mode enable_or_disable);
[Link] 32 FALSE [Link] eth0/0
[Link] 32 FALSE [Link] eth0/4
[Link] 24 TRUE - -
L3 Routing Implementation -> Phase 3 Defining IP Hdr Structure
➢ Defining IP Hdr
(Layer3/layer3.h)
➢ Writing Macros
➢ Assignment on IP Hdr
L3 Routing Implementation -> Phase 4 Topology used and ARP assumption
ARP Assumption :
> We shall assume that All routers have required ARP resolved already
> This is done to not to implement all complexity in one go, We shall deal how to resolve ARP on demand
after we are done with L3 Implementation
➢ Since, we are about to implement the L3 Routing, there should be infrastructure in place using which we can
incrementally test our L3 code
➢ Not every packet being routed by Network Layer is Data Link Layer
TCP/UDP packet
R1 R2
[Link]
How to test :
File : nwcli.c
Backend handler : R3
static int
[Link]
ping_handler(param_t *param, ser_buff_t *tlv_buf,
Ping success
op_mode enable_or_disable);
Which invokes :
Layer5/ping.c
extern void
layer5_ping_fn ( node_t *node, char *dst_ip_addr);
L3 Routing Implementation -> Phase 5 Implementing Ping
Transport Layer
(UDP/TCP Protocol)
• There is no explicit application data in the pkt (Only eth hdr and IP hdr)
• For ping : Source side is triggered by the application layer, On Destination side Network layer responds
L3 Routing Implementation -> Phase 5 Implementing Ping
ping [Link]
R1 R2 R3
Sets the ping Journey On L3 forwards the packet Reports “ping success”
L3 Routing Implementation -> Phase 6 Application and Network Layer Interaction
App Data
Layer 5
Application Layer
Layer3/layer3.c/.h
void
demote_pkt_to_layer3(node_t *node, /*Current node
char * pkt, /
unsigned int pkt_size, /*app data s
Layer5/layer5.c/.h int protocol_number, /*L5 protoc
unsigned int dest_ip_address); /*dest ip address
void
promote_pkt_to_layer5 (node_t *node, /*Current node on which the pkt is received*/
interface_t *recv_intf, /*ingress interface*/
char *payload, /*app data*/
uint32_t app_data_size); /*app data size*/
Layer 3
Network Layer
Layer2/layer2.c/.h
void
demote_pkt_to_layer2(node_t *node, /*Current node
uint32_t nexthop_ip, /*Gateway IP
char * pkt, /
Layer3/layer3.c/.h unsigned int pkt_size, /*app data s
int protocol_number); /*L3 protocol No = ET
void
promote_pkt_to_layer3 (node_t *node, /*Current node on which the pkt is received*/
interface_t *recv_intf, /*ingress interface*/
char *payload, /*app data*/
uint32_t app_data_size, /*app data size*/
int L3_protocol_Number); /*ethernet->type = ETH_IP*/
Layer3/layer3.c/.h
void
promote_pkt_to_layer3 (node_t *node, /*Current node on which the pkt is r
interface_t *recv_intf, /*ingress interface*/
char *payload, /*app data*/
uint32_t app_data_size, /*app data size*/
int L3_protocol_Number); /*ethernet->type = ET
void
demote_packet_to_layer3 (node_t *node,
char *pkt, unsigned int size,
int protocol_number, /*L4 or L5 protocol type*/
unsigned int dest_ip_address);
L3 Routing Implementation -> Phase 6 Data Link Layer APIs
Layer2/layer2.c/.h
void
promote_pkt_to_layer2 (node_t *node, /*Current node on which the pkt is r
interface_t *recv_intf, /*ingress interface*/
ethernet_hdr_t *ethernet_hdr,
uint32_t pkt_size);
void
demote_packet_to_layer2 (node_t *node,
unsigned int next_hop_ip,
char *outgoing_intf,
char *pkt, unsigned int pkt_size,
int protocol_number);
L3 Routing Implementation -> Phase 6 Application Layer APIs
Layer5/layer5.c
void
promote_pkt_to_layer5 (node_t *node, interface_t *recv_intf,
char *l5_hdr, uint32_t pkt_size,
uint32_t L5_protocol);
L3 Routing Implementation -> Phase 7 L3 Routing Revisited
D
[Link]/24
Dst IP :
[Link]
[Link]/24
eth6
1 [Link]/24
eth7
[Link]/24 2 eth1
eth1
1 Forwarding Case : Router ( = A) forwards the frame destined to remote subnet (dest = [Link])
2. Direct Host Delivery Case : Router (= B) forwards the frame destined to host present in locally connected subnet
(dest = [Link])
3 Local Delivery Case : Router ( = B) Or Host (= C) receives the pkt destined to itself )
4 Self ping Case : Any L3 device self originate the data destined to itself
(dst ip = self loopback or exact match of local interface address)
L3 Routing Implementation -> Phase 7 L3 Routing Revisited
D
[Link]/24
Dst IP :
[Link]
[Link]/24
eth6
1 [Link]/24
eth7
[Link]/24 2 eth1
eth1
interface_t *
net.c/.h
node_get_matching_subnet_interface(node_t *node, char *ip_addr);
L3 Routing Implementation -> Phase 7 L3 Routing Revisited
D
[Link]/24
Dst IP :
[Link]
[Link]/24
eth6
1 [Link]/24
eth7
[Link]/24 2 eth1
eth1
1. Data link layer handover the IP hdr of received frame to Network Layer
2. Network Layer checks if dst ip = IP of any local interface OR self-loopback then,
deliver the IP payload to higher layers based on protocol field value
L3 Routing Implementation -> Phase 7 L3 Routing Revisited
D
[Link]/24
Dst IP :
[Link]
[Link]/24
eth6
1 [Link]/24
eth7
[Link]/24 2 eth1
eth1
1. Network Layer receives the ping request from Higher Layer. Here Dest ip = Local interface IP Or
Self-Looback address
2. Network Layer looks-up in routing table for destination ip, it finds a local route
3. Network Layer handover the request to Layer 2 as per Direct host Deliver case
4. Data link layer checks, if dest-ip = exact match of any local interface Or loopback address, bounce the pkt back
to network layer
5. Network Layer exercise local delivery case
The intent is when routing device pings it-self, exercise the functionality of all the layers of TCP-IP stack – Ingress
and Egress
L3 Routing Implementation -> Phase 8 L3 Routing State Machine
D
[Link]/24
Dst IP :
[Link]
[Link]/24
eth6
1 [Link]/24
eth7
[Link]/24 2 eth1
eth1
1 Forwarding Case : Router ( = A) forwards the frame destined to remote subnet (dest = [Link])
2. Direct Host Delivery Case : Router (= B) forwards the frame destined to host present in locally connected subnet
(dest = [Link])
3 Local Delivery Case : Router ( = B) Or Host (= C) receives the pkt destined to itself )
4 Self ping Case : Any L3 device self originate the data destined to itself
(dst ip = self loopback or exact match of local interface address)
L3 Routing Implementation -> Phase 8 L3 Routing State Machine
Application layer
Transport Layer
Is 3
Is
N matching Y matching Y Is Dst IP Y
Discard entry = == Exact Local packet delivery
entry
local Match
found ?
subnet ?
N N
Depending on
Pkt belongs to
Remote
Pkt belongs to Value of
directly
subnet
connected
protocol field in
Forwarding 2 IP-hdr
host
Nxt-hop =
Nxt-Hop =
L3 Route look up Gateway
Dst
[Link]
L3 Routing Implementation -> Phase 8 L3 Routing State Machine
demote_packet_to_layer3(. . .)
Is N
Routing Table look up Remote
Route ?
Is Dest
Y IP = N
Y Local IP
Y Address
If Route
?
Found ?
2
demote_pkt_to_layer2(. . . )
As per forwarding Case demote_pkt_to_layer2(. . . )
N demote_pkt_to_layer2(. . . ) As per Direct host delivery
1 As per Self Ping case Case
Stop
4
• Pls feel free to insert as many debugging printfs as you want to triage the issues . . .
[Link]
L3 Routing Implementation -> Phase 8 L3 Routing State Machine
Application layer
Transport Layer
Is 3
Is
N matching Y matching Y Is Dst IP Y
Discard entry = == Exact Local packet delivery
entry
local Match
found ?
subnet ?
N N
Depending on
Pkt belongs to
Remote
Pkt belongs to Value of
directly
subnet
connected
protocol field in
Forwarding 2 IP-hdr
host
Nxt-hop =
Nxt-Hop =
L3 Route look up Gateway
Dst
[Link]
L3 Routing Implementation -> Phase 8 L3 Routing State Machine
demote_packet_to_layer3(. . .)
Is N
Routing Table look up Remote
Route ?
Is Dest
Y IP = N
Y Local IP
Y Address
If Route
?
Found ?
2
demote_pkt_to_layer2(. . . )
As per forwarding Case demote_pkt_to_layer2(. . . )
N demote_pkt_to_layer2(. . . ) As per Direct host delivery
1 As per Self Ping case Case
Stop
4
eth_hdr->type = ETH_IP
1 N 2 N
send_pkt_out(oif)
[Link]
L2 Routing Implementation
demote_pkt_to_layer2(. . . ) demote_pkt_to_layer2(. . . ) demote_pkt_to_layer2(. . . )
As per forwarding Case As per Self Ping case As per Direct host delivery
Case
1 4 2
Data Link Layer
eth_hdr->type = ETH_IP
1 N 2 N
send_pkt_out(oif)
[Link]
ARP On Demand
D
[Link]/24
Dst IP : [Link]/24 [Link]/24 eth1
[Link]/24
[Link] eth6 eth7 eth1
➢ As Soon as the Router A decides to L3 forward the Pkt P to Nexthop [Link] out of interface eth6,
it need to update the Ethernet hdr of the frame
➢ Suppose Router A do not have IP → MAC mapping in its ARP table for IP = [Link]
➢ Router A launch ARP Broadcast request on interface eth6 and wait for ARP reply
➢ Question : What will Router A do until ARP is resolved ?
➢ There could be other packets in Queue waiting to be treated by Router A
➢ Router A cannot wait !
➢ Solution :
➢ Router A temporarily stores the Pkt P, and get busy processing other incoming packets
➢ As soon as ARP resolution is done, Pkt P ‘s ethernet hdr is updated and forwarded
[Link]
ARP On Demand
D
[Link]/24
Dst IP : [Link]/24 [Link]/24 eth1
[Link]/24
[Link] eth6 eth7 eth1
D
[Link]/24
Dst IP : [Link]/24 [Link]/24 eth1
[Link]/24
[Link] eth6 eth7 eth1
➢ Each entry in ARP table maintains a list of packets whose ethernet hdr is incomplete
➢ These packets are awaiting ARP resolution
ARP On Demand
D
[Link]/24
Dst IP : [Link]/24 [Link]/24 eth1
[Link]/24
[Link] eth6 eth7 eth1
D
[Link]/24
Dst IP : [Link]/24 [Link]/24 eth1
[Link]/24
[Link] eth6 eth7 eth1
➢ Process ARP pending list : Update ethernet hdr of each pkt in ARP pending list and dispatch
ARP On Demand
Is C-ARP Is ARP
entry N sane N Create ARP sane
present entry for
X present entry
for X ?
?
Y Y
Send ARP Broadcast
Update ethernet request for X on oif
hdr and forward P
Queue P in ARP
pending list
ARP On Demand
Is ARP
Is C-ARP
N sane Y Unsane the ARP
entry
entry for
Process ARP
present entry, Complete pending list
X present
for X ? remaining fields
?
Iterate over ARP pending entries,
Fill up the ethernet hdr and dispatch
Y N
➢ Do your homework !!
L2
➢ In Real-World scenarios, End-hosts are connected to L2 switches and L2 switches Switch
IfR4
V=40,50 MR4
IfB
IfR3
B MB
L2 V=10,30 [Link]/30 MR3
Switch IfR1 [Link]/30
P2 P3 IfR2
[Link]/24
V=10 V=10,30 MR1 MR2
R1 R2
Lo: [Link]/32 Lo: [Link]/32
Mini Project
Ip-In-IP Encapsulation
➢ Now that we have implemented our beloved TCP/IP Stack, let us implement some networking mini projects or
concepts on top of it.
➢ Theory reference :
• Appendix G
➢ In the remaining part of this section, I assume you have understood the IP-in-IP encapsulation concept, and ready to
implement it
➢ Advice : Try implementing it yourself and refer to this section for help/reference. Learn to consume the remaining
portion of this course as a reference material
➢ Implementation Steps :
This CLI mean : R1 is sending ping packet to router R3 whose ip address is [Link] but ping packet
must go through router whose ip address [Link]
Simple ping !
R1 R2 R3
[Link]/32 [Link] eth0/0 eth0/0 [Link] eth0/2 [Link]
[Link] [Link]
eth0/5
Ero based ping !
R4
[Link]/32 [Link] eth0/5
Ip-In-IP Encapsulation
➢ Implementation Steps :
In Layer5/ping.c
void
layer3_ero_ping_fn (node_t *node, char *dst_ip_addr,
char *ero_ip_address);
Generated by CLI
➢ Call :
( Notice : Inner IP hdr just acts as a payload to
demote_packet_to_layer3 (node, (char *) inner_ip_hdr,
Network Layer)
inner_ip_hdr->total_length * 4,
IP_IN_IP, ero_ip_addr_int );
Ip-In-IP Encapsulation
➢ Implementation Steps :
In Layer5/ping.c
void
layer3_ero_ping_fn (node_t *node, char *dst_ip_addr,
char *ero_ip_address);
Generated by CLI
Final Pkt : Src ip : [Link] Dst ip = 122.1.4 Protocol = IP_IN_IP Src ip : [Link] Dst ip = [Link] Protocol = ICMP_PRO
➢ Implementation Steps :
➢ No Router ever sees the content of inner ip hdr as long as outer hdr is attached during the course of journey of the packet
➢ The TCP IP Stack will forward the pkt as usual until the packet reaches the ERO router (the dest for the outer ip hdr)
➢ No changes required in the forwarding logic of Network Layer
➢ When the packet Reaches ERO router, ERO router must set the pkt onto its new journey to ultimate destination
➢ Minor change is required in local host delivery case of Network Layer state diagram. Add the below case
In fn layer3_ip_pkt_recv_from_layer2(. . .) {
case IP_IN_IP: (This will set the pkt on its final course
layer3_ip_pkt_recv_from_layer2 (node, interface,
to ultimate destination !! )
(ip_hdr_t *)INCREMENT_IPHDR(ip_hdr),
IP_HDR_PAYLOAD_SIZE(ip_hdr));
return;
}
Done ☺
Developing
TCP/IP Stack
1. Interface Management & statistics
Part B
2. Dynamic L3 Route Calculation
No More Manual installation of L3 routes