PPPd over SOCAT using INTERFACE option - linux

My objective is to use pppd over socat. I have two Ubuntu boxes with eth0 connected (physically) to each other. I can ping both the IP addresses. I do the below on each Ubuntu box.
Create a pseudo serial device and link it to my network interface "eth0".socat PTY,link=/dev/ttyp10 INTERFACE:eth0
Use pppd on this pseudo serial device.
Device A:
pppd noauth /dev/ttyp10 10.10.10.10:20.20.20.20
Device B:
pppd noauth /dev/ttyp10 20.20.20.20:10.10.10.10
I see that my ppp0 interface gets created for a short time but I cannot ping both the IP addresses (10.10.10.10 or 20.20.20.20). I know my solution is not complete as I need to specify how my pppd packets must be routed from my eth0 interface but not sure how to do it (I used tcpdump on eth0 interface and found some data).
I tried the same experiment by binding socat to a TCP server/client and it worked.
Device A:
1. socat pty,link=/dev/ttyp10,raw,echo=0 TCP4-LISTEN:7001,reuseaddr &
2. pppd noauth /dev/ttyp10 10.10.10.10:20.20.20.20
Device B:
1. socat pty,link=/dev/ttyp10,raw,echo=0,waitslave TCP4:20.1.1.2:7001 &
2. pppd noauth /dev/ttyp10 20.20.20.20:10.10.10.10
Note: 20.1.1.2 is the "eth0" IP address of Device A. With this my ppp0 interface is up and I can ping both IP addresses (10.10.10.10 and 20.20.20.20).
Why I need to use the pseudo serial device when I have a working eth0 interface is a different question and lets not discuss that.

You probably want to adapt this example taken from the socat man page:
socat PTY,link=/var/run/ppp,rawer INTERFACE:hdlc0
circumvents the problem that pppd requires a serial device
and thus might not be able to work on a synchronous line
that is represented by a network device. socat creates a PTY
to make pppd happy, binds to the network interface hdlc0,
and can transfer data between both devices.
Use pppd on device /var/run/ppp then.
In this example, the interface is an synchronous line (seen by the OS as a HDLC interface). pppd uses (by default) a HLDC-like framing so it makes sense to pipe the raw data from pppd to the HDLC device.
In your case, you are using an Ethernet device and this does not make much sense to do the same thing.
In your second example, you managed to transport your PPP session over TCP which is a quite simple and viable option. Another solution in your case would be to use PPPoE which is designed for transporting PPP over Ethernet.

Related

Device and network interface

I have wifi and ethernet card in my computer.
Under linux is there a way to know which device is using which network interface?
Generally, you can run command "ip a" and check all the network interfaces connected: from the name of the interface you can see which kind of connection it's related to the interface, i.e.:
eth0
Some kind of cabled connection
wlp1
Some kind of wireless connection
This applies to default names, since you can always change the interface name.

Tun interface and IPv6

I'd like to ask you a question about tun interfaces, but without OpenVPN.
I have two applications that tunnel traffic:
"sgsn userspace app" reads IP packets from the tun interface "tun sgsn", sends them to "ggsn userspace app", this app writes them to "tun ggsn".
It works the other way too, so I can have a working ssh session, copy files, etc.
So, the packets go this way:
scp client --> sgsn tun interface ---> tunneling through my app -----> ggsn tun interface (dropped here) ----------> sshd
Now, I've tried it with IPv4 and it works, but when I switch to IPv6 the IP packet is written to "tun ggsn" and the IP stack discards it. I've seen it with dropwatch, which says the discard is in ip_rcv+c0.
The routes must be correct because otherwise the packet wouldn't have made it into tun_sgsn in the first place.
I've tried this in both CentOS 6.7 and 7.1 with same result. However, in the 7.1 I only have a single host, so I've done a few tricks with ip6tables to NAT addresses, so the traffic from each user space app (scp and sshd) goes through the tun interfaces. I'm saying this just so it's clear from the beginning, but with the 6.7 I have two machines and no NAT (I'm aware that NAT doesn't work in CentOS 6.7 for IPv6). I've used tcpdump in the tun ggsn interface and the IPv6 datagram seems all right.
Another hint: If I scp to the tun_ggsn interface directly, it works, but I don't think this discards anything with the tun driver, since being in the same machine that means the IP packets don't go down the TCP/IP stack to reach the tun driver (in fact, tcpdump does not capture the packet if I do this).
Any help would be appreciated, thank you very much in advance.

Linux bridge of my own making: arp request never succeeds

I wrote a bridge (layer 2 switch) using my Boost.Asio extension. We can easily make additional sockets, endpoints and protocols which meet their type requirements. And my extension uses linux packet socket with AF_PACKET, SOCK_RAW and htons(ETH_P_ALL) (See man 7 packet for more information about packet socket).
Here's an example for explaining how my bridge works:
[PC1] <----> IF1[PC2]IF2 <----> [PC3]
Bridge connects the network interfaces(e.g. eth0) IF1 and IF2 so PC1 can communicate with PC3 via bridge running on PC2. The way to connect interfaces is sending packets received from IF1 to IF2 (and vice versa)
My bridge works under the wired connections as expected, but it doesn't work under the wireless connections. So I tried to find what causes this problem and I found that ARP request never succeeded.
The actual environment which causes this problem is:
[PC1] <--wired--> eth0[PC2]wlan0 <--wireless(802.11g)--> [router1]
Under the environment above, for example, now PC1 tries to send ping(ICMP) packet to router1. To send it to PC3, PC1 has to know the MAC address of router1 so PC1 sends ARP request to FF:FF:FF:FF:FF:FF And my bridge running on PC2 receives it from eth0 and send it to wlan0, but router1 never sends arp reply to PC1.
note: SOCK_RAW packets are passed to and from the device driver without any changes in the packet data. (quoted from man page of packet)
What should I do to allow PC1 to communicate with router1?
Thank you.
Edit:
Here is my Boost.Asio extension.
github: pfpacket/libarex
And this is my bridge using above.
libarex/example/layer2_switch/interface_bridge.cpp
I'm writing up what we discussed in the comments.
It is a common problem that wireless bridging is problematic (under linux at least, I don't know for others). Investigation has shown that most probably the wireless driver or chipset of the hardware used as bridge is incapable of doing bridging operations (brctl failing supports this assumption).
Other possible reasons, as explained in the link above, may be the AP dropping packets with unassociated MAC adresses or the likes.
Additionally, the code works fine for wired interfaces, so it is a hardware problem on some layer. Not much more to say about it.

bond on software-bridge connection issue

What you have:
bond (bond0) interface (all modes except 4) with at least 2 ifaces (say eth0 / eth1) connected on the same external switch
bond0 interface joined on a software bridge (br0)
virtual machine (vm0) (eg LibVirt::LXC) with an interface on br0
What you get:
vm0 is not able to connect to (most) IP addresses via bond0 over br0
"bond0: received packet with own address as source address" in syslog
Why you get this:
When vm0 wants to contact an external IP address it will send out an ARP request. This L2 broadcast with the source mac of vm0 will leave through (depending on bonding mode) eg eth0, but via the external switch, re-enter through eth1 and thus bond0. Hence the switch br0 will learn the mac-address of vm0 on the port connected to bond0. As a consequence the ARP-reply is never received by vm0.
What can you do to resolve:
The reason I post this, next to sharing the info, is that I wasn't able to figure out a good enough solution. Those I did find are:
On vm0 set static ARP entry
Use bond0 mode=4 but your external switch must support this
Configure your external siwtch to use private VLAN on eth0/eth1 but only works in some use-cases and adds complexity
Add both physical interfaces to the bridge with spanning tree enabled, instead of using bond driver
Statically configuring the MAC of vm0 on the correct port of br0 is not an option on Linux (works on OpenBSD though)
I'm really hoping for a more elegant solution here... Anyone?
Thanks
I've got the same problem and I come up with the same analysis.
The only non-invasive/scalable solution I've found is to use the active/backup bonding (mode 1). The tradeoff is that you lose the aggregation.
IMO, the best solution is to use 802.3ad, but I can't always use it because I'm limited with 6 port-channels on most of my switches.
Try these options in bridge:
brigde_fd 0
bridge_stp off # switch on with more system like this
bridge_maxage 0
bridge_ageing 0
bridge_maxwait 0
Taken from this thread:
kvm bridge also in proxmox

How to route TCP/IP responses through a different interface?

I have two machines each with two valid network interfaces, an Ethernet interface eth0 and a tun/tap interface gr0. The goal is to start a TCP connection on machine A using interface gr0 but then have the responses (ACKs, etc) from machine B come back over the Ethernet interface, eth0. So, machine A sends out a SYN on gr0 and machine B receives the SYN on its own gr0 but then sends its SYN/ACK back through eth0. The tun/tap device is a GNU Radio wireless link and we just want the responses to come through the Ethernet.
What's the easiest way to accomplish this? I need to research more on TCP/IP, but I was initially thinking that source-spoofing outgoing packets would tell the receiver to respond to the spoofed address (which should get routed to eth0). This would involve routing the IPs from the tun/tap interfaces through gr0 and leave the other traffic to eth0.
We are using Linux and a Python solution would be preferable.
Thanks for looking!
You could add an additional address to the lo interface on each system and use these new addresses as the TCP connection endpoints. You can then use static routes to direct which path each machine takes to get to the other machine's lo address.
For example:
Machine A:
ip addr add 1.1.1.1/32 dev lo
ip route add 2.2.2.2/32 dev eth0 via <eth0 default gateway>
Machine B:
ip addr add 2.2.2.2/32 dev lo
ip route add 1.1.1.1/32 dev gr0
Then bind to 1.1.1.1 on machine A and connect to 2.2.2.2.
You may be interested in enabling logging of martian packets net.ipv4.conf.all.log_martians, and disable reverse path filtering net.ipv4.conf.<interface>.rp_filter on the affected interfaces.
This sysctl vars are accesible via the sysctl utility and/or the /proc filesystem.

Resources