Why do I see "martian source" logs in the messages file ?
Environment
- Red Hat Enterprise Linux (RHEL) all versions
- IPv4 networking
Issue
- Why do I see
martian sourcein the/var/log/messagesfile? - Why does the kernel log
martian sourcemessages?
kernel: martian source 192.168.0.1 from 192.168.0.255, on dev eth0
kernel: ll header: ff:ff:ff:ff:ff:ff:00:12:34:00:ab:cd:08:00
Resolution
Meaning
A "martian" is a packet received in a network interface, where the packet's source and/or destination IP address does not make sense.
Some examples of martian packets are:
- Source IP is already an address on the system receiving the packet
- Source IP is the broadcast address
255.255.255.255 - Source IP is the local subnet broadcast address
- Source IP is a multicast address
- Source IP not a unicast address
- Source or destination IP is zero
0.0.0.0 - Source or destination IP is a loopback address
127.0.0.0/8but was not received on the loopback interface - Source IP received in an unexpected interface
Martian source messages may indicate an issue with the network environment. You may wish to investigate:
- There are no layer 2 loops in the network: if the host sends a packet and then receives a copy of this packet back from the network, it will be logged as a martian
- There are no hosts transmitting traffic with a source IP which should not be used such as a multicast or broadcast IP
- The network addressing on all systems in the subnet is applied correctly and is valid, all hosts should have a valid IP address and the correct subnet mask (aka network prefix)
- Strict Reverse Path Forwarding filtering. Refer to How can I know if there is any packet discarded by strict filtering.
Reading Messages
A martian source message is laid out as follows:
kernel: martian source <destination IP> from <source IP>, on dev <interface packet arrived on>
kernel: ll header: <destination MAC address>:<source MAC address>:<ethertype> (for ethernet)
For example, given the message:
kernel: martian source 192.168.0.1 from 192.168.0.255, on dev eth0
kernel: ll header: ff:ff:ff:ff:ff:ff:00:12:34:00:ab:cd:08:00
- Destination IP:
192.168.0.1 - Source IP:
192.168.0.255 - Incoming interface:
eth0 - Destination MAC:
ff:ff:ff:ff:ff:ff - Source MAC:
00:12:34:00:ab:cd - Ethertype:
0x0800(IPv4)
In the above example, the packet is a martian because the network address of the receiver is 192.168.0.1/24. Given this local address, the address 192.168.0.255 is the subnet broadcast address and should never used as the source IP address of a packet.
In this situation, it is possible some other host has a larger subnet configured such as 192.168.0.255/23 which is a valid IP address in that larger /23 subnet, or the host has some process which is sending with an invalid source IP. You could find the source MAC address 00:12:34:00:ab:cd via the network infrastructure and investigate the system with that source MAC.
Configuration
The logging of martians can be controlled with the log_martians parameter as described at:
Root Cause
- Content from tools.ietf.org is not included.RFC1812 - Requirements for IP Version 4 Routers, section 5.3.7 Martian Address Filtering
- Content from en.wikipedia.org is not included.Martian packet - Wikipedia
RHEL 8 kernel source:
net/ipv4/route.c
static void ip_handle_martian_source(struct net_device *dev,
struct in_device *in_dev,
struct sk_buff *skb,
__be32 daddr,
__be32 saddr)
{
RT_CACHE_STAT_INC(in_martian_src);
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) {
/*
* RFC1812 recommendation, if source is martian,
* the only hint is MAC header.
*/
pr_warn("martian source %pI4 from %pI4, on dev %s\n",
&daddr, &saddr, dev->name);
if (dev->hard_header_len && skb_mac_header_was_set(skb)) {
print_hex_dump(KERN_WARNING, "ll header: ",
DUMP_PREFIX_OFFSET, 16, 1,
skb_mac_header(skb),
dev->hard_header_len, true);
}
}
#endif
}
RHEL 7 kernel source:
net/ipv4/route.c
static void ip_handle_martian_source(struct net_device *dev,
struct in_device *in_dev,
struct sk_buff *skb,
__be32 daddr,
__be32 saddr)
{
RT_CACHE_STAT_INC(in_martian_src);
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) {
/*
* RFC1812 recommendation, if source is martian,
* the only hint is MAC header.
*/
pr_warn("martian source %pI4 from %pI4, on dev %s\n",
&daddr, &saddr, dev->name);
if (dev->hard_header_len && skb_mac_header_was_set(skb)) {
print_hex_dump(KERN_WARNING, "ll header: ",
DUMP_PREFIX_OFFSET, 16, 1,
skb_mac_header(skb),
dev->hard_header_len, true);
}
}
#endif
}
RHEL 6 kernel source:
net/ipv4/route.c
static void ip_handle_martian_source(struct net_device *dev,
struct in_device *in_dev,
struct sk_buff *skb,
__be32 daddr,
__be32 saddr)
{
RT_CACHE_STAT_INC(in_martian_src);
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) {
/*
* RFC1812 recommendation, if source is martian,
* the only hint is MAC header.
*/
printk(KERN_WARNING "martian source %pI4 from %pI4, on dev %s\n",
&daddr, &saddr, dev->name);
if (dev->hard_header_len && skb_mac_header_was_set(skb)) {
int i;
const unsigned char *p = skb_mac_header(skb);
printk(KERN_WARNING "ll header: ");
for (i = 0; i < dev->hard_header_len; i++, p++) {
printk("%02x", *p);
if (i < (dev->hard_header_len - 1))
printk(":");
}
printk("\n");
}
}
#endif
}
RHEL 5 kernel source:
net/ipv4/route.c
static void ip_handle_martian_source(struct net_device *dev,
struct in_device *in_dev,
struct sk_buff *skb,
u32 daddr,
u32 saddr)
{
RT_CACHE_STAT_INC(in_martian_src);
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) {
/*
* RFC1812 recommendation, if source is martian,
* the only hint is MAC header.
*/
printk(KERN_WARNING "martian source %u.%u.%u.%u from "
"%u.%u.%u.%u, on dev %s\n",
NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
if (dev->hard_header_len && skb->mac.raw) {
int i;
unsigned char *p = skb->mac.raw;
printk(KERN_WARNING "ll header: ");
for (i = 0; i < dev->hard_header_len; i++, p++) {
printk("%02x", *p);
if (i < (dev->hard_header_len - 1))
printk(":");
}
printk("\n");
}
}
#endif
}
Diagnostic Steps
- As one of example, check the source and destination IP address in martian message. The both IP address looks healthy.
kernel: IPv4: martian source 10.10.10.255 from 10.10.10.10, on dev eth1
- In this case, check if the multiple interfaces are in the same subnet. The following routing table shows
eth0andeth1are in the same subnet. - This broadcast packet was received at
eth0first and then received ateth1. Thus, it is hit the example of Source IP is already an address on the system receiving the packet in the Resolution section.
# route
Destination Gateway Genmask Flags Metric Ref Use Iface
...
10.10.10.0 0.0.0.0 255.255.255.0 U 101 0 0 eth0 <<<---
10.10.10.0 0.0.0.0 255.255.255.0 U 102 0 0 eth1 <<<---
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.