Why do I see "martian source" logs in the messages file ?

Solution Verified - Updated

Environment

  • Red Hat Enterprise Linux (RHEL) all versions
  • IPv4 networking

Issue

  • Why do I see martian source in the /var/log/messages file?
  • Why does the kernel log martian source messages?
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/8 but 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

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 eth0 and eth1 are in the same subnet.
  • This broadcast packet was received at eth0 first and then received at eth1. 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   <<<---
Components
Category

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.