diff --git a/BUCK b/BUCK
new file mode 100644
index 0000000..9310e9e
--- /dev/null
+++ b/BUCK
@@ -0,0 +1,24 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:org.apache.karaf.shell.console',
+    '//cli:onos-cli',
+    '//apps/olt:onos-apps-olt-api',
+    '//apps/cordconfig:onos-apps-cordconfig',
+]
+
+BUNDLES = [
+    '//apps/olt:onos-apps-olt-api',
+    '//apps/igmp:onos-apps-igmp',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+)
+
+onos_app (
+    title = 'IGMP App',
+    category = 'Traffic Steering',
+    url = 'http://onosproject.org',
+    description = 'Internet Group Message Protocol',
+    included_bundles = BUNDLES,
+)
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..416c483
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-igmp</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Internet Group Message Protocol</description>
+
+    <properties>
+        <onos.app.name>org.onosproject.igmp</onos.app.name>
+        <onos.app.title>IGMP App</onos.app.title>
+        <onos.app.category>Traffic Steering</onos.app.category>
+        <onos.app.url>http://onosproject.org</onos.app.url>
+        <onos.app.readme>IGMP implementation.</onos.app.readme>
+        <onos.app.requires>org.onosproject.cord-config</onos.app.requires>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-olt-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cord-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- This is needed by ComponentContext, used for tunable configuration -->
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>
diff --git a/src/main/java/org/onosproject/igmp/IgmpSnoop.java b/src/main/java/org/onosproject/igmp/IgmpSnoop.java
new file mode 100644
index 0000000..aba5bbf
--- /dev/null
+++ b/src/main/java/org/onosproject/igmp/IgmpSnoop.java
@@ -0,0 +1,577 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.igmp;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IGMP;
+import org.onlab.packet.IGMPMembership;
+import org.onlab.packet.IGMPQuery;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.util.SafeRecurringTask;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cordconfig.access.AccessDeviceConfig;
+import org.onosproject.cordconfig.access.AccessDeviceData;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.mcast.McastRoute;
+import org.onosproject.net.mcast.MulticastRouteService;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Internet Group Management Protocol.
+ */
+@Component(immediate = true)
+public class IgmpSnoop {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final String DEST_MAC = "01:00:5E:00:00:01";
+    private static final String DEST_IP = "224.0.0.1";
+
+    private static final int DEFAULT_QUERY_PERIOD_SECS = 60;
+    private static final byte DEFAULT_IGMP_RESP_CODE = 100;
+
+    @Property(name = "multicastAddress",
+            label = "Define the multicast base range to listen to")
+    private String multicastAddress = IpPrefix.IPV4_MULTICAST_PREFIX.toString();
+
+    @Property(name = "queryPeriod", intValue = DEFAULT_QUERY_PERIOD_SECS,
+            label = "Delay in seconds between successive query runs")
+    private int queryPeriod = DEFAULT_QUERY_PERIOD_SECS;
+
+    @Property(name = "maxRespCode", byteValue = DEFAULT_IGMP_RESP_CODE,
+            label = "Maximum time allowed before sending a responding report")
+    private byte maxRespCode = DEFAULT_IGMP_RESP_CODE;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry networkConfig;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService componentConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MulticastRouteService multicastService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+
+    private ScheduledFuture<?> queryTask;
+    private final ScheduledExecutorService queryService =
+            Executors.newSingleThreadScheduledExecutor(groupedThreads("onos/igmp-query",
+                                                                      "membership-query"));
+
+    private Map<DeviceId, AccessDeviceData> oltData = new ConcurrentHashMap<>();
+
+    private Map<IpAddress, IpAddress> ssmTranslateTable = new ConcurrentHashMap<>();
+
+    private DeviceListener deviceListener = new InternalDeviceListener();
+    private IgmpPacketProcessor processor = new IgmpPacketProcessor();
+    private static ApplicationId appId;
+
+    private InternalNetworkConfigListener configListener =
+            new InternalNetworkConfigListener();
+
+    private static final Class<AccessDeviceConfig> CONFIG_CLASS =
+            AccessDeviceConfig.class;
+
+    private static final Class<IgmpSsmTranslateConfig> SSM_TRANSLATE_CONFIG_CLASS =
+            IgmpSsmTranslateConfig.class;
+
+    private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory =
+            new ConfigFactory<DeviceId, AccessDeviceConfig>(
+                    SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") {
+                @Override
+                public AccessDeviceConfig createConfig() {
+                    return new AccessDeviceConfig();
+                }
+            };
+
+    private ConfigFactory<ApplicationId, IgmpSsmTranslateConfig> ssmTranslateConfigFactory =
+            new ConfigFactory<ApplicationId, IgmpSsmTranslateConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY, SSM_TRANSLATE_CONFIG_CLASS, "ssmTranslate", true) {
+                @Override
+                public IgmpSsmTranslateConfig createConfig() {
+                    return new IgmpSsmTranslateConfig();
+                }
+            };
+
+
+    private ByteBuffer queryPacket;
+
+
+    @Activate
+    public void activate(ComponentContext context) {
+        componentConfigService.registerProperties(getClass());
+        modified(context);
+
+        appId = coreService.registerApplication("org.onosproject.igmp");
+
+        packetService.addProcessor(processor, PacketProcessor.director(1));
+
+        networkConfig.registerConfigFactory(configFactory);
+        networkConfig.registerConfigFactory(ssmTranslateConfigFactory);
+        networkConfig.addListener(configListener);
+
+        networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach(
+                subject -> {
+                    AccessDeviceConfig config = networkConfig.getConfig(subject,
+                                                                        AccessDeviceConfig.class);
+                    if (config != null) {
+                        AccessDeviceData data = config.getOlt();
+                        oltData.put(data.deviceId(), data);
+
+                    }
+                }
+        );
+
+        IgmpSsmTranslateConfig ssmTranslateConfig =
+                networkConfig.getConfig(appId, IgmpSsmTranslateConfig.class);
+
+        if (ssmTranslateConfig != null) {
+            Collection<McastRoute> translations = ssmTranslateConfig.getSsmTranslations();
+            for (McastRoute route : translations) {
+                ssmTranslateTable.put(route.group(), route.source());
+            }
+        }
+
+        oltData.keySet().stream()
+                .flatMap(did -> deviceService.getPorts(did).stream())
+                .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number()))
+                .filter(p -> p.isEnabled())
+                .forEach(p -> processFilterObjective((DeviceId) p.element().id(), p, false));
+
+        deviceService.addListener(deviceListener);
+
+        restartQueryTask();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        packetService.removeProcessor(processor);
+        processor = null;
+        deviceService.removeListener(deviceListener);
+        networkConfig.removeListener(configListener);
+        networkConfig.unregisterConfigFactory(configFactory);
+        networkConfig.unregisterConfigFactory(ssmTranslateConfigFactory);
+        queryTask.cancel(true);
+        queryService.shutdownNow();
+        componentConfigService.unregisterProperties(getClass(), false);
+        log.info("Stopped");
+    }
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
+
+        // TODO read multicastAddress from config
+        String strQueryPeriod = Tools.get(properties, "queryPeriod");
+        String strResponseCode = Tools.get(properties, "maxRespCode");
+        try {
+            byte newMaxRespCode = Byte.parseByte(strResponseCode);
+            if (maxRespCode != newMaxRespCode) {
+                maxRespCode = newMaxRespCode;
+                queryPacket = buildQueryPacket();
+            }
+
+            int newQueryPeriod = Integer.parseInt(strQueryPeriod);
+            if (newQueryPeriod != queryPeriod) {
+                queryPeriod = newQueryPeriod;
+                restartQueryTask();
+            }
+
+        } catch (NumberFormatException e) {
+            log.warn("Error parsing config input", e);
+        }
+
+        log.info("queryPeriod set to {}", queryPeriod);
+        log.info("maxRespCode set to {}", maxRespCode);
+    }
+
+    private void restartQueryTask() {
+        if (queryTask != null) {
+            queryTask.cancel(true);
+        }
+        queryPacket = buildQueryPacket();
+        queryTask = queryService.scheduleWithFixedDelay(
+                SafeRecurringTask.wrap(this::querySubscribers),
+                0,
+                queryPeriod,
+                TimeUnit.SECONDS);
+    }
+
+    private void processFilterObjective(DeviceId devId, Port port, boolean remove) {
+
+        //TODO migrate to packet requests when packet service uses filtering objectives
+        DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder();
+
+        builder = remove ? builder.deny() : builder.permit();
+
+        FilteringObjective igmp = builder
+                .withKey(Criteria.matchInPort(port.number()))
+                .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
+                .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
+                .withMeta(DefaultTrafficTreatment.builder()
+                                  .setOutput(PortNumber.CONTROLLER).build())
+                .fromApp(appId)
+                .withPriority(10000)
+                .add(new ObjectiveContext() {
+                    @Override
+                    public void onSuccess(Objective objective) {
+                        log.info("Igmp filter for {} on {} installed.",
+                                 devId, port);
+                    }
+
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.info("Igmp filter for {} on {} failed because {}.",
+                                 devId, port, error);
+                    }
+                });
+
+        flowObjectiveService.filter(devId, igmp);
+    }
+
+    private void processMembership(IGMP pkt, ConnectPoint location) {
+        pkt.getGroups().forEach(group -> {
+
+            if (!(group instanceof IGMPMembership)) {
+                log.warn("Wrong group type in IGMP membership");
+                return;
+            }
+
+            IGMPMembership membership = (IGMPMembership) group;
+
+            IpAddress groupAddress = membership.getGaddr();
+
+            if (membership.getRecordType() == IGMPMembership.MODE_IS_INCLUDE ||
+                    membership.getRecordType() == IGMPMembership.CHANGE_TO_INCLUDE_MODE) {
+
+                if (membership.getSources().isEmpty()) {
+                    McastRoute route = ssmTranslateRoute(groupAddress);
+                    if (route != null) {
+                        removeRoute(route, location);
+                    }
+                } else {
+                    membership.getSources().stream()
+                            .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP))
+                            .forEach(route -> addRoute(route, location));
+                }
+            } else if (membership.getRecordType() == IGMPMembership.MODE_IS_EXCLUDE ||
+                    membership.getRecordType() == IGMPMembership.CHANGE_TO_EXCLUDE_MODE) {
+
+                if (membership.getSources().isEmpty()) {
+                    McastRoute route = ssmTranslateRoute(groupAddress);
+                    if (route != null) {
+                        addRoute(route, location);
+                    }
+                } else {
+                    membership.getSources().stream()
+                            .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP))
+                            .forEach(route -> removeRoute(route, location));
+                }
+            }
+        });
+    }
+
+    private McastRoute ssmTranslateRoute(IpAddress group) {
+        IpAddress source = ssmTranslateTable.get(group);
+        if (source == null) {
+            log.warn("No SSM translate source found for group {}", group);
+            return null;
+        }
+        return new McastRoute(source, group, McastRoute.Type.IGMP);
+    }
+
+    private void addRoute(McastRoute route, ConnectPoint location) {
+        multicastService.add(route);
+        multicastService.addSink(route, location);
+    }
+
+    private void removeRoute(McastRoute route, ConnectPoint location) {
+        multicastService.removeSink(route, location);
+        // TODO remove route if all sinks are gone
+    }
+
+    private ByteBuffer buildQueryPacket() {
+        IGMP igmp = new IGMP();
+        igmp.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY);
+        igmp.setMaxRespCode(maxRespCode);
+
+        IGMPQuery query = new IGMPQuery(IpAddress.valueOf("0.0.0.0"), 0);
+        igmp.addGroup(query);
+
+        IPv4 ip = new IPv4();
+        ip.setDestinationAddress(DEST_IP);
+        ip.setProtocol(IPv4.PROTOCOL_IGMP);
+        ip.setSourceAddress("192.168.1.1");
+        ip.setTtl((byte) 1);
+        ip.setPayload(igmp);
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(DEST_MAC);
+        eth.setSourceMACAddress("DE:AD:BE:EF:BA:11");
+        eth.setEtherType(Ethernet.TYPE_IPV4);
+
+        eth.setPayload(ip);
+
+        eth.setPad(true);
+
+        return ByteBuffer.wrap(eth.serialize());
+    }
+
+    private void querySubscribers() {
+        oltData.keySet().stream()
+                .flatMap(did -> deviceService.getPorts(did).stream())
+                .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number()))
+                .filter(p -> p.isEnabled())
+                .forEach(p -> {
+                    TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                            .setOutput(p.number()).build();
+                    packetService.emit(new DefaultOutboundPacket((DeviceId) p.element().id(),
+                                                                 treatment, queryPacket));
+                });
+    }
+
+    /**
+     * Packet processor responsible for handling IGMP packets.
+     */
+    private class IgmpPacketProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+            // Stop processing if the packet has been handled, since we
+            // can't do any more to it.
+            if (context.isHandled()) {
+                return;
+            }
+
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethPkt = pkt.parsed();
+            if (ethPkt == null) {
+                return;
+            }
+
+
+            // IPv6 MLD packets are handled by ICMP6. We'll only deal with IPv4.
+            if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
+                return;
+            }
+
+            IPv4 ip = (IPv4) ethPkt.getPayload();
+            IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
+            IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress());
+            log.trace("Packet ({}, {}) -> ingress port: {}", saddr, gaddr,
+                      context.inPacket().receivedFrom());
+
+
+            if (ip.getProtocol() != IPv4.PROTOCOL_IGMP ||
+                    !IpPrefix.IPV4_MULTICAST_PREFIX.contains(gaddr)) {
+                return;
+            }
+
+            if (IpPrefix.IPV4_MULTICAST_PREFIX.contains(saddr)) {
+                log.debug("IGMP Picked up a packet with a multicast source address.");
+                return;
+            }
+
+            IGMP igmp = (IGMP) ip.getPayload();
+            switch (igmp.getIgmpType()) {
+                case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT:
+                    processMembership(igmp, pkt.receivedFrom());
+                    break;
+
+                case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY:
+                    log.debug("Received a membership query {} from {}",
+                              igmp, pkt.receivedFrom());
+                    break;
+
+                case IGMP.TYPE_IGMPV1_MEMBERSHIP_REPORT:
+                case IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT:
+                case IGMP.TYPE_IGMPV2_LEAVE_GROUP:
+                    log.debug("IGMP version 1 & 2 message types are not currently supported. Message type: {}",
+                              igmp.getIgmpType());
+                    break;
+                default:
+                    log.warn("Unknown IGMP message type: {}", igmp.getIgmpType());
+                    break;
+            }
+        }
+    }
+
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            DeviceId devId = event.subject().id();
+            switch (event.type()) {
+
+                case DEVICE_ADDED:
+                case DEVICE_UPDATED:
+                case DEVICE_REMOVED:
+                case DEVICE_SUSPENDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case PORT_STATS_UPDATED:
+                    break;
+                case PORT_ADDED:
+                    if (!oltData.get(devId).uplink().equals(event.port().number()) &&
+                            event.port().isEnabled()) {
+                        processFilterObjective(event.subject().id(), event.port(), false);
+                    }
+                    break;
+                case PORT_UPDATED:
+                    if (oltData.get(devId).uplink().equals(event.port().number())) {
+                        break;
+                    }
+                    if (event.port().isEnabled()) {
+                        processFilterObjective(event.subject().id(), event.port(), false);
+                    } else {
+                        processFilterObjective(event.subject().id(), event.port(), true);
+                    }
+                    break;
+                case PORT_REMOVED:
+                    processFilterObjective(event.subject().id(), event.port(), true);
+                    break;
+                default:
+                    log.warn("Unknown device event {}", event.type());
+                    break;
+            }
+        }
+
+        @Override
+        public boolean isRelevant(DeviceEvent event) {
+            return oltData.containsKey(event.subject().id());
+        }
+    }
+
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            switch (event.type()) {
+
+                case CONFIG_ADDED:
+                case CONFIG_UPDATED:
+                    if (event.configClass().equals(CONFIG_CLASS)) {
+                        AccessDeviceConfig config =
+                                networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS);
+                        if (config != null) {
+                            oltData.put(config.getOlt().deviceId(), config.getOlt());
+                            provisionDefaultFlows((DeviceId) event.subject());
+                        }
+                    }
+                    if (event.configClass().equals(SSM_TRANSLATE_CONFIG_CLASS)) {
+                        IgmpSsmTranslateConfig config =
+                                networkConfig.getConfig((ApplicationId) event.subject(),
+                                        SSM_TRANSLATE_CONFIG_CLASS);
+
+                        if (config != null) {
+                            ssmTranslateTable.clear();
+                            config.getSsmTranslations().forEach(
+                                    route -> ssmTranslateTable.put(route.group(), route.source()));
+                        }
+                    }
+                    break;
+                case CONFIG_REGISTERED:
+                case CONFIG_UNREGISTERED:
+                    break;
+                case CONFIG_REMOVED:
+                    if (event.configClass().equals(SSM_TRANSLATE_CONFIG_CLASS)) {
+                        ssmTranslateTable.clear();
+                    } else if (event.configClass().equals(CONFIG_CLASS)) {
+                        oltData.remove(event.subject());
+                    }
+
+                default:
+                    break;
+            }
+        }
+    }
+
+    private void provisionDefaultFlows(DeviceId deviceId) {
+        List<Port> ports = deviceService.getPorts(deviceId);
+
+        ports.stream()
+                .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number()))
+                .filter(p -> p.isEnabled())
+                .forEach(p -> processFilterObjective((DeviceId) p.element().id(), p, false));
+    }
+}
diff --git a/src/main/java/org/onosproject/igmp/IgmpSsmTranslateConfig.java b/src/main/java/org/onosproject/igmp/IgmpSsmTranslateConfig.java
new file mode 100644
index 0000000..ddc6209
--- /dev/null
+++ b/src/main/java/org/onosproject/igmp/IgmpSsmTranslateConfig.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.igmp;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.mcast.McastRoute;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * IGMP SSM translate configuration.
+ */
+public class IgmpSsmTranslateConfig extends Config<ApplicationId> {
+
+    private static final String SOURCE = "source";
+    private static final String GROUP = "group";
+
+    @Override
+    public boolean isValid() {
+        for (JsonNode node : array) {
+            if (!hasOnlyFields((ObjectNode) node, SOURCE, GROUP)) {
+                return false;
+            }
+
+            if (!(isIpAddress((ObjectNode) node, SOURCE, FieldPresence.MANDATORY) &&
+                    isIpAddress((ObjectNode) node, GROUP, FieldPresence.MANDATORY))) {
+                return false;
+            }
+
+        }
+        return true;
+    }
+
+    /**
+     * Gets the list of SSM translations.
+     *
+     * @return SSM translations
+     */
+    public List<McastRoute> getSsmTranslations() {
+        List<McastRoute> translations = new ArrayList();
+        for (JsonNode node : array) {
+            translations.add(
+                    new McastRoute(
+                            IpAddress.valueOf(node.path(SOURCE).asText().trim()),
+                            IpAddress.valueOf(node.path(GROUP).asText().trim()),
+                            McastRoute.Type.STATIC));
+        }
+
+        return translations;
+    }
+}
diff --git a/src/main/java/org/onosproject/igmp/package-info.java b/src/main/java/org/onosproject/igmp/package-info.java
new file mode 100644
index 0000000..f501339
--- /dev/null
+++ b/src/main/java/org/onosproject/igmp/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * IGMP implementation.
+ */
+package org.onosproject.igmp;
