iproute2 commands for MPLS configuration - linux

Trying to figure out how one can use iproute2 to manage static label-switched MPLS routes in Linux kernel 4.1.
I am aware iproute2 support for MPLS might be incomplete right now [2].
Can anyone please shed some light on what iproute2-4.1.1 is currently able to do?
This is what I have found so far:
Documentation/networking/mpls-sysctl.txt
/proc/sys/net/mpls/platform_labels
/proc/sys/net/mpls/conf//input
Load mpls module
sudo modprobe mpls_router
Find sysctl support
sysctl -a --pattern mpls
net.mpls.conf.eth0.input = 0
net.mpls.conf.eth1.input = 0
net.mpls.conf.lo.input = 0
net.mpls.platform_labels = 0
Enable mpls support
sudo sysctl -w net.mpls.conf.eth0.input=1
sudo sysctl -w net.mpls.conf.eth1.input=1
sudo sysctl -w net.mpls.platform_labels=1000
push??? (how to add prefix-to-push action?)
sudo ip route add 1.1.1.1/32 via mpls 100/200/300 dev eth0
swap??? (how to add label-swap action?)
sudo ip -f mpls route add 10 via mpls 100/200/300 dev eth0
pop??? (how to add label-pop action?)
???
show??? (how to display label-switched routes?)
???
Can someone help me out .
Thanks in Advance.

A little bit too late, but hope it helps somebody. You can find them here:
Routing 10.10.10.10/32 to 192.168.1.2 with label 100:
ip route add 10.10.10.10/32 encap mpls 100 via inet 192.168.1.2
Label swapping 100 for 200 and sent to 192.168.2.2:
ip -f mpls route add 100 as 200 via inet 192.168.2.2
Decapsulating label 300 and delivering locally:
ip -f mpls route add 300 dev lo
To show MPLS routes you can do:
ip -f mpls route show
If your iproute2 version doesn't support those commands, you can get it from here:
https://www.kernel.org/pub/linux/utils/net/iproute2/iproute2-4.6.0.tar.gz
And then
./configure && make && make install

Related

RTNETLINK answers: Invalid argument, MPLS on mininet

I am trying to apply MPLS on mininet and I was able to install iproute2, the problem that I have is when I try to use any command in the format
ip -f mpls xxx
I always get an error.
I was able to inser a route
mininet> r1 ip route add 10.0.4.0/24 encap mpls 400 via inet 172.16.1.2
mininet> r1 ip route show
10.0.1.0/24 dev r1-eth0 proto kernel scope link src 10.0.1.1
10.0.4.0/24 encap mpls 400 via 172.16.1.2 dev r1-eth1
172.16.1.0/24 dev r1-eth1 proto kernel scope link src 172.16.1.1
but I am not able to see it using the correct command for mpls
mininet> r1 ip -f mpls route show
mininet>
also when I try to do a swap of the labels I get an error
mininet> r5 ip -f mpls route add 400 as 405 via inet 172.16.8.2
RTNETLINK answers: Invalid argument
any help will be greatly appreciated.
UPDATE
I solved my problem by changing the value on /proc/sys/net/mpls/platform_labels the value set here will be the highest label value that can be used
I solved my problem by changing the value on /proc/sys/net/mpls/platform_labels the value set here will be the highest label value that can be used
But keep in mind that I have to set this value for all the devices on my mininet network as well as loading the mpls module and any parameter
* modprobe mpls_router
* modprobe mpls_gso
* modprobe mpls_iptunnel
* sysctl -w net.mpls.platform_labels=1048575
* sysctl -w net.mpls.conf.*-eth#.input=1 #for every interface that speaks mpls
I thought that doing it in it kernel will activate it for all, but apparently it has to be done within every device on the network

Ubuntu keeps losing resolv.conf settings?

Every time I reboot my ubuntu server, it loses it's nameserver setting. I have to run:
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
each time I reboot for it to work properly again.
I tried editing resolv.conf directly and still doesn't work properly.
Any advice?
Edit below file for making effect on every time when you reboot
This is head section of resolve conf which added in resolve.conf
/etc/resolvconf/resolv.conf.d/head
In Ubuntu 18.04 thats working:
Sudo rm /etc/resolv.conf
sudo echo "nameserver xxx.xxx.xxx.xxx" >> /etc/systemd/resolve/resolv.conf
sudo ln -s /etc/systemd/resolve/resolv.conf /etc/resolv.conf
But I think a better option would be to edit the /etc/network/interfaces file and configure the system correctly, including the dns you need, for example:
auto lo
iface lo inet loopback
auto enp0s3
iface enp0s3 inet dhcp
dns-nameservers 8.8.8.8 8.8.4.4
In this example the first two lines define the local interface, do not touch it, the third line says that when the computer boots up the network card enp0s3 simultaneously (you can find out the name of your network card(s) with the command ifconfig -a), the fourth line tells the enp0s3 card to listen to a dhcp server and take the data needed for its network configuration from there, and the last line tells it which dns you want to use.
If you know your network configuration, it will always be the same or you don't have a dhcp server, the file would be something like this:
auto lo
iface lo inet loopback
auto enp0s3
iface enp0s3 inet static
address 10.10.5.67
netmask 255.255.255.0
gateway 10.10.5.1
broadcast 10.10.5.255
dns-nameservers 8.8.8.8 8.8.4.4
Another possibility is to configure the netplan file, the new default mode to manage the network from ubuntu 17.10 Artful. Here you can see more on the subject, particularly I don't like it but I am aware of its power for complex cases.
You can keep settings by editing a base file.
Install resolvconf:
sudo apt-get install resolvconf
Edit /etc/resolvconf/resolv.conf.d/base:
sudo vi /etc/resolvconf/resolv.conf.d/base
Add your nameserver:
nameserver 8.8.8.8
Start resolvconf:
sudo /etc/init.d/resolvconf start
Check that /etc/resolv.conf contains the following line:
nameserver 8.8.8.8
Then try to restart your server and check /etc/resolv.conf again.
That happens because of resolvconf. As the man page states, it allows other programs to change the DNS resolver configuration. Probably, there is a DHCP server on your network that is providing your host its IP address and the DSN servers.
You can change the DHCP configuration or force the first lines of resolv.confas #sahilKataria suggested. Using your command:
echo "nameserver 8.8.8.8" | sudo tee /etc/resolvconf/resolv.conf.d/head
Edit your netplan file. Example:
sudo vim /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
enp0s31f6:
dhcp4: true # Using DHCP
dhcp4-overrides: # Override DHCP
use-dns: false # Disable DHCP DNS
routes:
- to: x.x.x.x/24
via: x.x.x.x
metric: 100
- to: x.x.x.x/24
via: x.x.x.x
metric: 100
nameservers: # Name Server section
search: [somename.ddns.net] # Set your nameserver search
addresses: [x.x.x.x] # Set your DNS Server
version: 2
When you are done, run:
netplan apply
And make sure that you have this:
$ ls -ltra /etc/resolv.conf
/etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
If bind is installed on the same machine:
$ cat /etc/hosts
127.0.1.1 somename.ddns.net somename # example
bind-ipaddress somename.ddns.net somename # example

networking is not working on qemu guest (Malta Mips)

I am trying to configure networking on QEMU malta mips, which is running on vmware host (ubuntu) using tap/tun device and bridge interface. My qemu guest is unable to retrieve ip address from DHCP server. If i give it manually, it can just connect with its host. Using tcpdump i came to know that outgoing traffic is working perfectly but incoming is not working.
Can anyone suggest me how to solve this kind of issue?
Thank You
If you use NAT mode, then your host machine will act as a router for your guest VM. This means you must enable routing on your host.
Assuming you start qemu and link it to tap0 interface and your outgoing internet interface is eth0, then you should:
Create the tap0 virtual interface:
tunctl -t tap0
ifconfig tap0 192.168.0.1 netmask 255.255.255.0 up
Activate routing
# activate ip forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# Create forwarding rules, where
# tap0 - virtual interface
# eth0 - net connected interface
iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o tap0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Start your VM with somenthing like this:
qemu [..] -net nic,model=e1000,vlan=0 -net tap,ifname=tap0,vlan=0,script=no
In your VM, configure an interface with ip 192.168.0.2/24 and default gateway 192.168.0.1
In NAT mode you can't achieve this. You need to configure VM in bridge mode and I hope you know the steps to configure it; if not see the link here ;
Step #2 of catalin.me's answer could be even simpler:
# activate ip forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
First two iptables rules are needed only in case if default policy for FORWARD chain is DROP.
E.g.:
iptables -P FORWARD DROP

Isolated test network on a Linux server running a web server (lightttpd) and (curl) clients

I'm writing a testing tool that requires known traffic to be captured from a NIC (using libpcap), then fed into the application we are trying to test.
What I'm attempting to set-up is a web server (in this case, lighttpd) and a client (curl) running on the same machine, on an isolated test network. A script will drive the entire setup, and the goal is to be able to specify a number of clients as well as a set of files for each client to download from the web server.
My initial approach was to simply use the loopback (lo) interface... run the web server on 127.0.0.1, have the clients fetch their files from http://127.0.0.1, and run my libpcap-based tool on the lo interface. This works ok, apart from the fact that the loopback interface doesn't emulate a real Ethernet interface. The main problem with that is that packets are all inconsistent sizes... 32kbytes and bigger, and somewhat random... it's also not possible to lower the MTU on lo (well, you can, but it has no effect!).
I also tried running it on my real interface (eth0), but since it's an internal web client talking to an internal web server, traffic never leaves the interface, so libpcap never sees it.
So then I turned to tun/tap. I used socat to bind two tun interfaces together with a tcp connection, so in effect, i had:
10.0.1.1/24 <-> tun0 <-socat-> tcp connection <-socat-> tun1 <-> 10.0.2.1/24
This seems like a really neat solution... tun/tap devices emulate real Ethernet devices, so i can run my web server on tun0 (10.0.1.1) and my capture tool on tun0, and bind my clients to tun1 (10.0.2.1)... I can even use tc to apply shaping rules to this traffic and create a virtual WAN inside my linux box... but it just doesn't work...
Here are the socat commands I used:
$ socat -d TCP-LISTEN:11443,reuseaddr TUN:10.0.1.1/24,up &
$ socat TCP:127.0.0.1:11443 TUN:10.0.2.1/24,up &
Which produces 2 tun interfaces (tun0 and tun1), with their respective IP addresses.
If I run ping -I tun1 10.0.1.1, there is no response, but when i tcpdump -n -i tun0, i see the ICMP echo requests making it to the other side, just no sign of the response coming back.
# tcpdump -i tun0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 65535 bytes
16:49:16.772718 IP 10.0.2.1 > 10.0.1.1: ICMP echo request, id 4062, seq 5, length 64
<--- insert sound of crickets here (chirp, chirp)
So am I missing something obvious or is this the wrong approach? Is there something else i can try (e.g. 2 physical interfaces, eth0 and eth1???).
The easiest way is just to use 2 machines, but I want all of this self-contained, so it can all be scripted and automated on a single machine, without and other dependencies...
UPDATE:
There is no need for the 2 socats to be connected with a tcp connection, it's possible (and preferable for me) to do this:
socat TUN:10.0.1.1/24,up TUN:10.0.2.1/24,up &
The same problem still exists though...
OK, so I found a solution using Linux network namespaces (netns). There is a helpful article about how to use it here: http://code.google.com/p/coreemu/wiki/Namespaces
This is what I did for my setup....
First, download and install CORE: http://cs.itd.nrl.navy.mil/work/core/index.php
Next, run this script:
#!/bin/sh
core-cleanup.sh > /dev/null 2>&1
ip link set vbridge down > /dev/null 2>&1
brctl delbr vbridge > /dev/null 2>&1
# create a server node namespace container - node 0
vnoded -c /tmp/n0.ctl -l /tmp/n0.log -p /tmp/n0.pid > /dev/null
# create a virtual Ethernet (veth) pair, installing one end into node 0
ip link add name veth0 type veth peer name n0.0
ip link set n0.0 netns `cat /tmp/n0.pid`
vcmd -c /tmp/n0.ctl -- ip link set n0.0 name eth0
vcmd -c /tmp/n0.ctl -- ifconfig eth0 10.0.0.1/24 up
# start web server on node 0
vcmd -I -c /tmp/n0.ctl -- lighttpd -f /etc/lighttpd/lighttpd.conf
# create client node namespace container - node 1
vnoded -c /tmp/n1.ctl -l /tmp/n1.log -p /tmp/n1.pid > /dev/null
# create a virtual Ethernet (veth) pair, installing one end into node 1
ip link add name veth1 type veth peer name n1.0
ip link set n1.0 netns `cat /tmp/n1.pid`
vcmd -c /tmp/n1.ctl -- ip link set n1.0 name eth0
vcmd -c /tmp/n1.ctl -- ifconfig eth0 10.0.0.2/24 up
# bridge together nodes using the other end of each veth pair
brctl addbr vbridge
brctl setfd vbridge 0
brctl addif vbridge veth0
brctl addif vbridge veth1
ip link set veth0 up
ip link set veth1 up
ip link set vbridge up
This basically sets up 2 virtual/isolated/name-spaced networks on your Linux host, in this case, node 0 and node 1. A web server is started on node 0.
All you need to do now is run curl on node 1:
vcmd -c /tmp/n1.ctl -- curl --output /dev/null http://10.0.0.1
And monitor the traffic with tcpdump:
tcpdump -s 1514 -i veth0 -n
This seems to work quite well... still experimenting, but looks like it will solve my problem.

How to route in linux

I have 20 ips from my isp. I have them bound to a router box running centos. What commands, and in what order, do I set up so that the other boxes on my lan, based either on their mac addresses or 192 ips can I have them route out my box on specific ips. For example I want mac addy xxx:xxx:xxx0400 to go out 72.049.12.157 and xxx:xxx:xxx:0500 to go out 72.049.12.158.
Use iptables to setup NAT.
iptables -t nat -I POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 72.049.12.157
iptables -t nat -I POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 72.049.12.158
This should cause any ips on the 192.168.0.0 subnet to have an 'external' ip of 72.049.12.157 and those on the 192.168.1.0 subnet to have an 'external' ip of 72.049.12.158. For MAC address matching, use -m mac --mac-source MAC-ADDRESS in place of the -s 192.168.0.0/24 argument
Don't forget to activate ip forwarding:
cat /proc/sys/net/ipv4/ip_forward
If the above returns a 0 then it won't work, you'll have to enable it. Unfortunately this is distro-specific and I don't know CentOS.
For a quick hack, do this:
echo 1 > /proc/sys/net/ipv4/ip_forward
What's the router hardware and software version?
Are you trying to do this with a linux box? Stop now and go get a router. It will save you money long-term.
Answering this question with the little information you gave amounts to rewriting a routing Howto here. You could either
read about routing and IP in general (e.g. Linux System Administrator's Guide) or
give us more info on the exact IP addresses you got.
The above answer using NAT is definately not what you intend to use when you have public IP addresses. This solution is not going to scale well.

Resources