diff --git a/easy-qos/files/etc/init.d/easy_qos.classcfg b/easy-qos/files/etc/init.d/easy_qos.classcfg
index 822512f5627c951b8ee1f3de7782801b7ade8a9c..e9a3c82e96a4c36f80688a4f09e2a44678758061 100755
--- a/easy-qos/files/etc/init.d/easy_qos.classcfg
+++ b/easy-qos/files/etc/init.d/easy_qos.classcfg
@@ -4,6 +4,7 @@ START=99
 USE_PROCD=1
 
 RULE_LIST="/tmp/easy_qos_rule.list"
+CLIENT_LIST="/tmp/easy_qos_class_client.list"
 BRIDGE_INTF=""
 
 [ -f /etc/profile.d/intel.sh ] && {
@@ -16,6 +17,13 @@ log() {
 }
 
 exec_log() {
+	${@}
+	if [ "${?}" -ne 0 ]; then
+		log "Failed to create ${@}";
+	fi
+}
+
+exec_class_log() {
 	${@} |grep -i successful
 	if [ "${?}" -ne 0 ]; then
 		log "Failed to create ${@}";
@@ -46,6 +54,114 @@ get_priority() {
 	esac
 }
 
+get_mark() {
+	local prio=$(echo $1|tr [A-Z] [a-z]);
+	case "${prio}" in
+		"lowest")
+			echo "0x41/0x3df";;
+		"low")
+			echo "0x82/0x3df";;
+		"besteffort")
+			echo "0xc3/0x3df";;
+		"normal")
+			echo "0x104/0x3df";;
+		"video")
+			echo "0x145/0x3df";;
+		"medium")
+			echo "0x186/0x3df";;
+		"high")
+			echo "0x1c7/0x3df";;
+		"highest")
+			echo "0x208/0x3df";;
+	esac
+}
+
+clean_client_entries() {
+	[ -f ${CLIENT_LIST} ] && rm ${CLIENT_LIST}
+}
+
+map_client_entries() {
+	local clients ip mac host
+
+	json_load "$(ubus call router.network 'clients')"
+	json_get_keys keys
+
+	for key in ${keys};
+	do
+		json_select ${key}
+		json_get_vars ipaddr macaddr hostname
+		clients="${macaddr} ${ipaddr} ${hostname};${clients}"
+		json_select ..
+	done
+
+	json_init
+
+	IFS=";"
+	for client in ${clients};
+	do
+		macaddr=$(echo ${client} | cut -d" " -f1)
+		json_add_object "${macaddr//:/_}"
+		json_add_string "ip" "$(echo ${client} | cut -d" " -f2)"
+		json_add_string "macaddr" "$(echo ${client} | cut -d" " -f1)"
+		json_add_string "host" "$(echo ${client} | cut -d" " -f3)"
+		json_close_object
+	done
+
+	IFS=' '
+	echo `json_dump` > ${CLIENT_LIST}
+	json_cleanup
+}
+
+# Find the IP of a corresponding mac from arp table
+get_ipaddress() {
+	local clients ip mac host
+
+	json_load "$(cat ${CLIENT_LIST})"
+	json_get_keys keys
+
+	# jshn seems a bit iffy on having : in key, replace by _
+	json_select "${1//:/_}" 2 > /dev/null
+	json_get_var ip ip
+
+	echo "$ip"
+}
+
+check_and_create() {
+	iptables -t mangle -C PREROUTING ${@} 2>/dev/null
+	# Create rule if not exists
+	if [ ${?} -ne 0 ]; then
+		exec_log iptables -t mangle -A PREROUTING ${@}
+	else
+		log "Rule exists for ${@}"
+	fi
+}
+
+create_ip_rule() {
+	local proto=$1; shift
+	local src_ip=$1; shift
+	local mark=$1; shift
+	local ports=$1;
+	local cmd="";
+
+	cmd="-j EXTMARK --set-mark ${mark}";
+	if [ "${proto}" != "icmp" ]; then
+		if [ -n "${ports}" ]; then
+			cmd="--match multiport --dports ${ports} ${cmd}";
+		fi
+	fi
+
+	if [ "${proto}" == "icmp" ]; then
+		cmd="-p icmp -m icmp --icmp-type 8 $cmd"
+	elif [ "${proto}" == "all" ]; then
+		cmd="-p all $cmd"
+	else
+		cmd="-p ${proto} -m ${proto} $cmd"
+	fi
+	cmd="-s ${src_ip} $cmd"
+
+	check_and_create ${cmd}
+}
+
 is_lan_bridge() {
 	local _section=$1
 	local _type
@@ -67,10 +183,10 @@ get_bridge_interface() {
 validate_rule_section()
 {
 	uci_validate_section easy_qos rule "${1}" \
-		'priority:string:none' \
-		'macaddr:string:none' \
+		'priority:string' \
+		'macaddr:string' \
 		'proto:string:none' \
-		'port:list(uinteger):none' \
+		'port:list(uinteger)' \
 		'comment:string:none'
 }
 
@@ -82,8 +198,14 @@ clear_existing_rules() {
 	while read line
 	do
 		log "Deleting old classification rules"
-		exec_log classcfg -D ${line} -i ${BRIDGE_INTF}
+		exec_class_log classcfg -D ${line} -i ${BRIDGE_INTF}
 	done <${RULE_LIST}
+
+	local rule=$(iptables -t mangle -S PREROUTING|grep -m 1 EXTMARK |sed 's/-A/-D/1')
+	while [ -n "${rule}" ]; do
+		exec_log iptables -t mangle ${rule}
+		rule=$(iptables -t mangle -S PREROUTING|grep -m 1 EXTMARK |sed 's/-A/-D/1')
+	done
 	sync
 
 	[ -f ${RULE_LIST} ] && rm ${RULE_LIST}
@@ -104,13 +226,16 @@ create_rule() {
 	if [ "${mac_addr}" != "none" ]; then
 		cmd="--smac ${mac_addr} ${cmd}";
 	fi
-	if [ "${ports}" != "none" ]; then
-		IFS=","
-		for port in ${ports};
-		do
-			cmd="--dport ${port}:${port} ${cmd}";
-		done
-		IFS=' '
+
+	if [ "${proto}" != "icmp" ]; then
+		if [ "${ports}" != "none" ]; then
+			IFS=","
+			for port in ${ports};
+			do
+				cmd="--dport ${port}:${port} ${cmd}";
+			done
+			IFS=' '
+		fi
 	fi
 	if [ "${proto}" != "none" ]; then
 		cmd="-p ${proto} $cmd"
@@ -119,14 +244,14 @@ create_rule() {
 	cmd="-A ${rule_name} $cmd"
 
 	# Store the rule_names for cleanup on reload
-	exec_log classcfg ${cmd} 
+	exec_class_log classcfg ${cmd}
 	[ $? -eq 0 ] && \
 		echo ${rule_name}  >> ${RULE_LIST}
 }
 
 manage_rule() {
 	local cfg="$1"
-	local priority macaddr proto port comment prio_num port_list
+	local priority macaddr proto port comment prio_num port_list ip ipmark
 
 	validate_rule_section "${1}" || {
 		log "Validation of section failed"
@@ -135,22 +260,33 @@ manage_rule() {
 
 	prio_num=$(get_priority ${priority})
 	port_list=$(echo ${port}|sed 's/ /,/g')
+	ipmark=$(get_mark ${priority})
+	ip=$(get_ipaddress ${macaddr})
 
 	if [ -n "${prio_num}" ]; then
 		if [ "${proto}" == "none" -o "${proto}" == "tcpudp" ]; then
 			create_rule tcp ${macaddr} ${prio_num} ${port_list}
 			create_rule udp ${macaddr} ${prio_num} ${port_list}
+			if [ -n "${ip}" ]; then
+				create_ip_rule tcp ${ip} ${ipmark} ${port_list}
+				create_ip_rule udp ${ip} ${ipmark} ${port_list}
+			fi
 		else
 			create_rule ${proto} ${macaddr} ${prio_num} ${port_list}
+			if [ -n "${ip}" ]; then
+				create_ip_rule ${proto} ${ip} ${ipmark} ${port_list}
+			fi
 		fi
 	fi
 }
 
 reload_service() {
 	get_bridge_interface
+	map_client_entries
 	clear_existing_rules
 	config_load easy_qos
 	config_foreach manage_rule rule
+	clean_client_entries
 }
 
 start_service() {