summaryrefslogtreecommitdiff
path: root/net/ipv4/igmp.c
diff options
context:
space:
mode:
authorSrinivasarao P <spathi@codeaurora.org>2018-01-09 16:12:59 +0530
committerSrinivasarao P <spathi@codeaurora.org>2018-01-18 12:50:10 +0530
commitfb9c0ae7a810d2724ee293d26462fcaaa33a4703 (patch)
tree8b1a6660f12462caaf76bf45133eef16f772df6b /net/ipv4/igmp.c
parent3726391f0570b5c8889d1db5f02a6a0a622c65b2 (diff)
parent8cbe01c651bb2c03da371703faebcc602a40e61c (diff)
Merge android-4.4.109 (8cbe01c) into msm-4.4
* refs/heads/tmp-8cbe01c Linux 4.4.109 mm/vmstat: Make NR_TLB_REMOTE_FLUSH_RECEIVED available even on UP n_tty: fix EXTPROC vs ICANON interaction with TIOCINQ (aka FIONREAD) x86/smpboot: Remove stale TLB flush invocations nohz: Prevent a timer interrupt storm in tick_nohz_stop_sched_tick() usb: xhci: Add XHCI_TRUST_TX_LENGTH for Renesas uPD720201 USB: Fix off by one in type-specific length check of BOS SSP capability usb: add RESET_RESUME for ELSA MicroLink 56K usb: Add device quirk for Logitech HD Pro Webcam C925e USB: serial: option: adding support for YUGA CLM920-NC5 USB: serial: option: add support for Telit ME910 PID 0x1101 USB: serial: qcserial: add Sierra Wireless EM7565 USB: serial: ftdi_sio: add id for Airbus DS P8GR usbip: vhci: stop printing kernel pointer addresses in messages usbip: stub: stop printing kernel pointer addresses in messages usbip: fix usbip bind writing random string after command in match_busid sock: free skb in skb_complete_tx_timestamp on error net: phy: micrel: ksz9031: reconfigure autoneg after phy autoneg workaround net: Fix double free and memory corruption in get_net_ns_by_id() net: bridge: fix early call to br_stp_change_bridge_id and plug newlink leaks ipv4: Fix use-after-free when flushing FIB tables sctp: Replace use of sockets_allocated with specified macro. net: mvmdio: disable/unprepare clocks in EPROBE_DEFER case net: ipv4: fix for a race condition in raw_sendmsg tg3: Fix rx hang on MTU change with 5717/5719 tcp md5sig: Use skb's saddr when replying to an incoming segment net: reevalulate autoflowlabel setting after sysctl setting net: qmi_wwan: add Sierra EM7565 1199:9091 netlink: Add netns check on taps net: igmp: Use correct source address on IGMPv3 reports ipv6: mcast: better catch silly mtu values ipv4: igmp: guard against silly MTU values kbuild: add '-fno-stack-check' to kernel build options x86/mm/64: Fix reboot interaction with CR4.PCIDE x86/mm: Enable CR4.PCIDE on supported systems x86/mm: Add the 'nopcid' boot option to turn off PCID x86/mm: Disable PCID on 32-bit kernels x86/mm: Remove the UP asm/tlbflush.h code, always use the (formerly) SMP code x86/mm: Reimplement flush_tlb_page() using flush_tlb_mm_range() x86/mm: Make flush_tlb_mm_range() more predictable x86/mm: Remove flush_tlb() and flush_tlb_current_task() x86/vm86/32: Switch to flush_tlb_mm_range() in mark_screen_rdonly() ALSA: hda - fix headset mic detection issue on a Dell machine ALSA: hda: Drop useless WARN_ON() ASoC: twl4030: fix child-node lookup ASoC: fsl_ssi: AC'97 ops need regmap, clock and cleaning up on failure iw_cxgb4: Only validate the MSN for successful completions ring-buffer: Mask out the info bits when returning buffer page length tracing: Fix crash when it fails to alloc ring buffer tracing: Fix possible double free on failure of allocating trace buffer tracing: Remove extra zeroing out of the ring buffer page net: mvneta: clear interface link status on port disable powerpc/perf: Dereference BHRB entries safely kvm: x86: fix RSM when PCID is non-zero KVM: X86: Fix load RFLAGS w/o the fixed bit spi: xilinx: Detect stall with Unknown commands parisc: Hide Diva-built-in serial aux and graphics card PCI / PM: Force devices to D0 in pci_pm_thaw_noirq() ALSA: usb-audio: Fix the missing ctl name suffix at parsing SU ALSA: rawmidi: Avoid racy info ioctl via ctl device mfd: twl6040: Fix child-node lookup mfd: twl4030-audio: Fix sibling-node lookup mfd: cros ec: spi: Don't send first message too soon crypto: mcryptd - protect the per-CPU queue with a lock ACPI: APEI / ERST: Fix missing error handling in erst_reader() Change-Id: I3823f793c0c85d1639e9be10358cf70cfcd13afc Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r--net/ipv4/igmp.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 3809d523d012..b60106d34346 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -89,6 +89,7 @@
#include <linux/rtnetlink.h>
#include <linux/times.h>
#include <linux/pkt_sched.h>
+#include <linux/byteorder/generic.h>
#include <net/net_namespace.h>
#include <net/arp.h>
@@ -327,6 +328,23 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
return scount;
}
+/* source address selection per RFC 3376 section 4.2.13 */
+static __be32 igmpv3_get_srcaddr(struct net_device *dev,
+ const struct flowi4 *fl4)
+{
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
+
+ if (!in_dev)
+ return htonl(INADDR_ANY);
+
+ for_ifa(in_dev) {
+ if (inet_ifa_match(fl4->saddr, ifa))
+ return fl4->saddr;
+ } endfor_ifa(in_dev);
+
+ return htonl(INADDR_ANY);
+}
+
static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
{
struct sk_buff *skb;
@@ -374,7 +392,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
pip->frag_off = htons(IP_DF);
pip->ttl = 1;
pip->daddr = fl4.daddr;
- pip->saddr = fl4.saddr;
+ pip->saddr = igmpv3_get_srcaddr(dev, &fl4);
pip->protocol = IPPROTO_IGMP;
pip->tot_len = 0; /* filled in later */
ip_select_ident(net, skb, NULL);
@@ -410,16 +428,17 @@ static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
}
static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
- int type, struct igmpv3_grec **ppgr)
+ int type, struct igmpv3_grec **ppgr, unsigned int mtu)
{
struct net_device *dev = pmc->interface->dev;
struct igmpv3_report *pih;
struct igmpv3_grec *pgr;
- if (!skb)
- skb = igmpv3_newpack(dev, dev->mtu);
- if (!skb)
- return NULL;
+ if (!skb) {
+ skb = igmpv3_newpack(dev, mtu);
+ if (!skb)
+ return NULL;
+ }
pgr = (struct igmpv3_grec *)skb_put(skb, sizeof(struct igmpv3_grec));
pgr->grec_type = type;
pgr->grec_auxwords = 0;
@@ -441,12 +460,17 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
struct igmpv3_grec *pgr = NULL;
struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list;
int scount, stotal, first, isquery, truncate;
+ unsigned int mtu;
if (pmc->multiaddr == IGMP_ALL_HOSTS)
return skb;
if (ipv4_is_local_multicast(pmc->multiaddr) && !sysctl_igmp_llm_reports)
return skb;
+ mtu = READ_ONCE(dev->mtu);
+ if (mtu < IPV4_MIN_MTU)
+ return skb;
+
isquery = type == IGMPV3_MODE_IS_INCLUDE ||
type == IGMPV3_MODE_IS_EXCLUDE;
truncate = type == IGMPV3_MODE_IS_EXCLUDE ||
@@ -467,7 +491,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) {
if (skb)
igmpv3_sendpack(skb);
- skb = igmpv3_newpack(dev, dev->mtu);
+ skb = igmpv3_newpack(dev, mtu);
}
}
first = 1;
@@ -494,12 +518,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
pgr->grec_nsrcs = htons(scount);
if (skb)
igmpv3_sendpack(skb);
- skb = igmpv3_newpack(dev, dev->mtu);
+ skb = igmpv3_newpack(dev, mtu);
first = 1;
scount = 0;
}
if (first) {
- skb = add_grhead(skb, pmc, type, &pgr);
+ skb = add_grhead(skb, pmc, type, &pgr, mtu);
first = 0;
}
if (!skb)
@@ -533,7 +557,7 @@ empty_source:
igmpv3_sendpack(skb);
skb = NULL; /* add_grhead will get a new one */
}
- skb = add_grhead(skb, pmc, type, &pgr);
+ skb = add_grhead(skb, pmc, type, &pgr, mtu);
}
}
if (pgr)