Lines Matching full:h

45 #include <linux/module.h>
46 #include <linux/kernel.h>
47 #include <linux/netdevice.h>
48 #include <linux/nospec.h>
49 #include <linux/etherdevice.h>
50 #include <linux/dvb/net.h>
51 #include <linux/uio.h>
52 #include <linux/uaccess.h>
53 #include <linux/crc32.h>
54 #include <linux/mutex.h>
55 #include <linux/sched.h>
57 #include <media/dvb_demux.h>
58 #include <media/dvb_net.h>
316 static int dvb_net_ule_new_ts_cell(struct dvb_net_ule_handle *h) in dvb_net_ule_new_ts_cell() argument
323 memcpy(ule_where, h->ts, TS_SZ); in dvb_net_ule_new_ts_cell()
332 * Check TS h->error conditions: sync_byte, transport_error_indicator, in dvb_net_ule_new_ts_cell()
335 if ((h->ts[0] != TS_SYNC) || (h->ts[1] & TS_TEI) || in dvb_net_ule_new_ts_cell()
336 ((h->ts[3] & TS_SC) != 0)) { in dvb_net_ule_new_ts_cell()
338 h->priv->ts_count, h->ts[0], in dvb_net_ule_new_ts_cell()
339 (h->ts[1] & TS_TEI) >> 7, in dvb_net_ule_new_ts_cell()
340 (h->ts[3] & TS_SC) >> 6); in dvb_net_ule_new_ts_cell()
343 if (h->priv->ule_skb) { in dvb_net_ule_new_ts_cell()
344 dev_kfree_skb(h->priv->ule_skb); in dvb_net_ule_new_ts_cell()
346 h->dev->stats.rx_errors++; in dvb_net_ule_new_ts_cell()
347 h->dev->stats.rx_frame_errors++; in dvb_net_ule_new_ts_cell()
349 reset_ule(h->priv); in dvb_net_ule_new_ts_cell()
350 h->priv->need_pusi = 1; in dvb_net_ule_new_ts_cell()
353 h->ts += TS_SZ; in dvb_net_ule_new_ts_cell()
354 h->priv->ts_count++; in dvb_net_ule_new_ts_cell()
358 h->ts_remain = 184; in dvb_net_ule_new_ts_cell()
359 h->from_where = h->ts + 4; in dvb_net_ule_new_ts_cell()
364 static int dvb_net_ule_ts_pusi(struct dvb_net_ule_handle *h) in dvb_net_ule_ts_pusi() argument
366 if (h->ts[1] & TS_PUSI) { in dvb_net_ule_ts_pusi()
369 h->priv->tscc = h->ts[3] & 0x0F; in dvb_net_ule_ts_pusi()
371 if (h->ts[4] > h->ts_remain) { in dvb_net_ule_ts_pusi()
373 h->priv->ts_count, h->ts[4]); in dvb_net_ule_ts_pusi()
374 h->ts += TS_SZ; in dvb_net_ule_ts_pusi()
375 h->priv->ts_count++; in dvb_net_ule_ts_pusi()
379 h->from_where = &h->ts[5] + h->ts[4]; in dvb_net_ule_ts_pusi()
380 h->ts_remain -= 1 + h->ts[4]; in dvb_net_ule_ts_pusi()
381 h->skipped = 0; in dvb_net_ule_ts_pusi()
383 h->skipped++; in dvb_net_ule_ts_pusi()
384 h->ts += TS_SZ; in dvb_net_ule_ts_pusi()
385 h->priv->ts_count++; in dvb_net_ule_ts_pusi()
392 static int dvb_net_ule_new_ts(struct dvb_net_ule_handle *h) in dvb_net_ule_new_ts() argument
395 if ((h->ts[3] & 0x0F) == h->priv->tscc) in dvb_net_ule_new_ts()
396 h->priv->tscc = (h->priv->tscc + 1) & 0x0F; in dvb_net_ule_new_ts()
400 h->priv->ts_count, h->ts[3] & 0x0F, in dvb_net_ule_new_ts()
401 h->priv->tscc); in dvb_net_ule_new_ts()
403 if (h->priv->ule_skb) { in dvb_net_ule_new_ts()
404 dev_kfree_skb(h->priv->ule_skb); in dvb_net_ule_new_ts()
406 // reset_ule(h->priv); moved to below. in dvb_net_ule_new_ts()
407 h->dev->stats.rx_errors++; in dvb_net_ule_new_ts()
408 h->dev->stats.rx_frame_errors++; in dvb_net_ule_new_ts()
410 reset_ule(h->priv); in dvb_net_ule_new_ts()
412 h->priv->need_pusi = 1; in dvb_net_ule_new_ts()
421 if (h->ts[1] & TS_PUSI) { in dvb_net_ule_new_ts()
422 if (!h->priv->need_pusi) { in dvb_net_ule_new_ts()
423 if (!(*h->from_where < (h->ts_remain-1)) || in dvb_net_ule_new_ts()
424 *h->from_where != h->priv->ule_sndu_remain) { in dvb_net_ule_new_ts()
430 h->priv->ts_count, in dvb_net_ule_new_ts()
431 *h->from_where); in dvb_net_ule_new_ts()
437 if (h->priv->ule_skb) { in dvb_net_ule_new_ts()
438 h->error = true; in dvb_net_ule_new_ts()
439 dev_kfree_skb(h->priv->ule_skb); in dvb_net_ule_new_ts()
442 if (h->error || h->priv->ule_sndu_remain) { in dvb_net_ule_new_ts()
443 h->dev->stats.rx_errors++; in dvb_net_ule_new_ts()
444 h->dev->stats.rx_frame_errors++; in dvb_net_ule_new_ts()
445 h->error = false; in dvb_net_ule_new_ts()
448 reset_ule(h->priv); in dvb_net_ule_new_ts()
449 h->priv->need_pusi = 1; in dvb_net_ule_new_ts()
456 h->from_where += 1; in dvb_net_ule_new_ts()
457 h->ts_remain -= 1; in dvb_net_ule_new_ts()
459 h->priv->need_pusi = 0; in dvb_net_ule_new_ts()
461 if (h->priv->ule_sndu_remain > 183) { in dvb_net_ule_new_ts()
466 h->dev->stats.rx_errors++; in dvb_net_ule_new_ts()
467 h->dev->stats.rx_length_errors++; in dvb_net_ule_new_ts()
468 …pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, h->ts_remain %d). Flushing incomp… in dvb_net_ule_new_ts()
469 h->priv->ts_count, in dvb_net_ule_new_ts()
470 h->priv->ule_sndu_remain, in dvb_net_ule_new_ts()
471 h->ts[4], h->ts_remain); in dvb_net_ule_new_ts()
472 dev_kfree_skb(h->priv->ule_skb); in dvb_net_ule_new_ts()
474 reset_ule(h->priv); in dvb_net_ule_new_ts()
479 h->from_where += h->ts[4]; in dvb_net_ule_new_ts()
480 h->ts_remain -= h->ts[4]; in dvb_net_ule_new_ts()
492 * Check h.ts_remain has to be >= 2 here.
494 static int dvb_net_ule_new_payload(struct dvb_net_ule_handle *h) in dvb_net_ule_new_payload() argument
496 if (h->ts_remain < 2) { in dvb_net_ule_new_payload()
498 h->ts_remain); in dvb_net_ule_new_payload()
499 h->priv->ule_sndu_len = 0; in dvb_net_ule_new_payload()
500 h->priv->need_pusi = 1; in dvb_net_ule_new_payload()
501 h->ts += TS_SZ; in dvb_net_ule_new_payload()
505 if (!h->priv->ule_sndu_len) { in dvb_net_ule_new_payload()
507 h->priv->ule_sndu_len = h->from_where[0] << 8 | in dvb_net_ule_new_payload()
508 h->from_where[1]; in dvb_net_ule_new_payload()
509 if (h->priv->ule_sndu_len & 0x8000) { in dvb_net_ule_new_payload()
511 h->priv->ule_sndu_len &= 0x7FFF; in dvb_net_ule_new_payload()
512 h->priv->ule_dbit = 1; in dvb_net_ule_new_payload()
514 h->priv->ule_dbit = 0; in dvb_net_ule_new_payload()
516 if (h->priv->ule_sndu_len < 5) { in dvb_net_ule_new_payload()
518 h->priv->ts_count, in dvb_net_ule_new_payload()
519 h->priv->ule_sndu_len); in dvb_net_ule_new_payload()
520 h->dev->stats.rx_errors++; in dvb_net_ule_new_payload()
521 h->dev->stats.rx_length_errors++; in dvb_net_ule_new_payload()
522 h->priv->ule_sndu_len = 0; in dvb_net_ule_new_payload()
523 h->priv->need_pusi = 1; in dvb_net_ule_new_payload()
524 h->new_ts = 1; in dvb_net_ule_new_payload()
525 h->ts += TS_SZ; in dvb_net_ule_new_payload()
526 h->priv->ts_count++; in dvb_net_ule_new_payload()
529 h->ts_remain -= 2; /* consume the 2 bytes SNDU length. */ in dvb_net_ule_new_payload()
530 h->from_where += 2; in dvb_net_ule_new_payload()
533 h->priv->ule_sndu_remain = h->priv->ule_sndu_len + 2; in dvb_net_ule_new_payload()
536 * h->ts_remain (remaining bytes in the current TS cell) in dvb_net_ule_new_payload()
541 switch (h->ts_remain) { in dvb_net_ule_new_payload()
543 h->priv->ule_sndu_remain--; in dvb_net_ule_new_payload()
544 h->priv->ule_sndu_type = h->from_where[0] << 8; in dvb_net_ule_new_payload()
547 h->priv->ule_sndu_type_1 = 1; in dvb_net_ule_new_payload()
548 h->ts_remain -= 1; in dvb_net_ule_new_payload()
549 h->from_where += 1; in dvb_net_ule_new_payload()
552 h->new_ts = 1; in dvb_net_ule_new_payload()
553 h->ts += TS_SZ; in dvb_net_ule_new_payload()
554 h->priv->ts_count++; in dvb_net_ule_new_payload()
559 if (h->priv->ule_sndu_type_1) { in dvb_net_ule_new_payload()
560 h->priv->ule_sndu_type_1 = 0; in dvb_net_ule_new_payload()
561 h->priv->ule_sndu_type |= h->from_where[0]; in dvb_net_ule_new_payload()
562 h->from_where += 1; /* points to payload start. */ in dvb_net_ule_new_payload()
563 h->ts_remain -= 1; in dvb_net_ule_new_payload()
566 h->priv->ule_sndu_type = h->from_where[0] << 8 | in dvb_net_ule_new_payload()
567 h->from_where[1]; in dvb_net_ule_new_payload()
568 h->from_where += 2; /* points to payload start. */ in dvb_net_ule_new_payload()
569 h->ts_remain -= 2; in dvb_net_ule_new_payload()
581 h->priv->ule_skb = dev_alloc_skb(h->priv->ule_sndu_len + in dvb_net_ule_new_payload()
583 if (!h->priv->ule_skb) { in dvb_net_ule_new_payload()
585 h->dev->name); in dvb_net_ule_new_payload()
586 h->dev->stats.rx_dropped++; in dvb_net_ule_new_payload()
591 h->priv->ule_sndu_remain = h->priv->ule_sndu_len; in dvb_net_ule_new_payload()
592 h->priv->ule_skb->dev = h->dev; in dvb_net_ule_new_payload()
597 skb_reserve(h->priv->ule_skb, ETH_HLEN + ETH_ALEN); in dvb_net_ule_new_payload()
603 static int dvb_net_ule_should_drop(struct dvb_net_ule_handle *h) in dvb_net_ule_should_drop() argument
613 if (h->priv->rx_mode == RX_MODE_PROMISC) in dvb_net_ule_should_drop()
616 if (h->priv->ule_skb->data[0] & 0x01) { in dvb_net_ule_should_drop()
618 if (!ether_addr_equal(h->priv->ule_skb->data, bc_addr)) { in dvb_net_ule_should_drop()
620 if (h->priv->rx_mode == RX_MODE_MULTI) { in dvb_net_ule_should_drop()
623 for (i = 0; i < h->priv->multi_num && in dvb_net_ule_should_drop()
624 !ether_addr_equal(h->priv->ule_skb->data, in dvb_net_ule_should_drop()
625 h->priv->multi_macs[i]); in dvb_net_ule_should_drop()
628 if (i == h->priv->multi_num) in dvb_net_ule_should_drop()
630 } else if (h->priv->rx_mode != RX_MODE_ALL_MULTI) in dvb_net_ule_should_drop()
638 } else if (!ether_addr_equal(h->priv->ule_skb->data, h->dev->dev_addr)) in dvb_net_ule_should_drop()
645 static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h, in dvb_net_ule_check_crc() argument
653 h->priv->ts_count, ule_crc, expected_crc, in dvb_net_ule_check_crc()
654 h->priv->ule_sndu_len, h->priv->ule_sndu_type, in dvb_net_ule_check_crc()
655 h->ts_remain, in dvb_net_ule_check_crc()
656 h->ts_remain > 2 ? in dvb_net_ule_check_crc()
657 *(unsigned short *)h->from_where : 0); in dvb_net_ule_check_crc()
677 h->dev->stats.rx_errors++; in dvb_net_ule_check_crc()
678 h->dev->stats.rx_crc_errors++; in dvb_net_ule_check_crc()
679 dev_kfree_skb(h->priv->ule_skb); in dvb_net_ule_check_crc()
687 h->priv->ule_skb->tail -= 4; in dvb_net_ule_check_crc()
688 h->priv->ule_skb->len -= 4; in dvb_net_ule_check_crc()
690 if (!h->priv->ule_dbit) { in dvb_net_ule_check_crc()
691 if (dvb_net_ule_should_drop(h)) { in dvb_net_ule_check_crc()
692 netdev_dbg(h->dev, in dvb_net_ule_check_crc()
693 "Dropping SNDU: MAC destination address does not match: dest addr: %pM, h->dev addr: %pM\n", in dvb_net_ule_check_crc()
694 h->priv->ule_skb->data, h->dev->dev_addr); in dvb_net_ule_check_crc()
695 dev_kfree_skb(h->priv->ule_skb); in dvb_net_ule_check_crc()
699 skb_copy_from_linear_data(h->priv->ule_skb, dest_addr, in dvb_net_ule_check_crc()
701 skb_pull(h->priv->ule_skb, ETH_ALEN); in dvb_net_ule_check_crc()
703 /* dest_addr buffer is only valid if h->priv->ule_dbit == 0 */ in dvb_net_ule_check_crc()
708 if (h->priv->ule_sndu_type < ETH_P_802_3_MIN) { in dvb_net_ule_check_crc()
710 int l = handle_ule_extensions(h->priv); in dvb_net_ule_check_crc()
719 dev_kfree_skb(h->priv->ule_skb); in dvb_net_ule_check_crc()
722 skb_pull(h->priv->ule_skb, l); in dvb_net_ule_check_crc()
727 * Note: in bridged mode (h->priv->ule_bridged != 0) in dvb_net_ule_check_crc()
733 if (!h->priv->ule_bridged) { in dvb_net_ule_check_crc()
734 skb_push(h->priv->ule_skb, ETH_HLEN); in dvb_net_ule_check_crc()
735 h->ethh = (struct ethhdr *)h->priv->ule_skb->data; in dvb_net_ule_check_crc()
736 memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN); in dvb_net_ule_check_crc()
737 eth_zero_addr(h->ethh->h_source); in dvb_net_ule_check_crc()
738 h->ethh->h_proto = htons(h->priv->ule_sndu_type); in dvb_net_ule_check_crc()
741 h->priv->ule_bridged = 0; in dvb_net_ule_check_crc()
744 h->priv->ule_skb->protocol = dvb_net_eth_type_trans(h->priv->ule_skb, in dvb_net_ule_check_crc()
745 h->dev); in dvb_net_ule_check_crc()
751 if (h->priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) in dvb_net_ule_check_crc()
752 h->priv->ule_skb->pkt_type = PACKET_HOST; in dvb_net_ule_check_crc()
754 h->dev->stats.rx_packets++; in dvb_net_ule_check_crc()
755 h->dev->stats.rx_bytes += h->priv->ule_skb->len; in dvb_net_ule_check_crc()
756 netif_rx(h->priv->ule_skb); in dvb_net_ule_check_crc()
762 struct dvb_net_ule_handle h = { in dvb_net_ule() local
782 for (h.ts = h.buf, h.ts_end = h.buf + h.buf_len; in dvb_net_ule()
783 h.ts < h.ts_end; /* no incr. */) { in dvb_net_ule()
784 if (h.new_ts) { in dvb_net_ule()
786 if (dvb_net_ule_new_ts_cell(&h)) in dvb_net_ule()
791 if (h.priv->need_pusi) { in dvb_net_ule()
792 if (dvb_net_ule_ts_pusi(&h)) in dvb_net_ule()
796 if (h.new_ts) { in dvb_net_ule()
797 if (dvb_net_ule_new_ts(&h)) in dvb_net_ule()
802 if (h.priv->ule_skb == NULL) { in dvb_net_ule()
803 ret = dvb_net_ule_new_payload(&h); in dvb_net_ule()
811 h.how_much = min(h.priv->ule_sndu_remain, (int)h.ts_remain); in dvb_net_ule()
812 skb_put_data(h.priv->ule_skb, h.from_where, h.how_much); in dvb_net_ule()
813 h.priv->ule_sndu_remain -= h.how_much; in dvb_net_ule()
814 h.ts_remain -= h.how_much; in dvb_net_ule()
815 h.from_where += h.how_much; in dvb_net_ule()
818 if (h.priv->ule_sndu_remain <= 0) { in dvb_net_ule()
820 __be16 ulen = htons(h.priv->ule_sndu_len); in dvb_net_ule()
821 __be16 utype = htons(h.priv->ule_sndu_type); in dvb_net_ule()
826 { h.priv->ule_skb->data, in dvb_net_ule()
827 h.priv->ule_skb->len - 4 } in dvb_net_ule()
830 if (h.priv->ule_dbit) { in dvb_net_ule()
837 tail = skb_tail_pointer(h.priv->ule_skb); in dvb_net_ule()
843 dvb_net_ule_check_crc(&h, iov, ule_crc, expected_crc); in dvb_net_ule()
846 reset_ule(h.priv); in dvb_net_ule()
850 if (h.ts_remain >= 2 && *((unsigned short *)h.from_where) != 0xFFFF) { in dvb_net_ule()
852 h.new_ts = 0; in dvb_net_ule()
853 h.priv->ule_skb = NULL; in dvb_net_ule()
854 h.priv->ule_sndu_type_1 = 0; in dvb_net_ule()
855 h.priv->ule_sndu_len = 0; in dvb_net_ule()
857 // *(h.from_where + 0), *(h.from_where + 1), in dvb_net_ule()
858 // *(h.from_where + 2), *(h.from_where + 3)); in dvb_net_ule()
859 // pr_warn("h.ts @ %p, stopped @ %p:\n", h.ts, h.from_where + 0); in dvb_net_ule()
860 // hexdump(h.ts, 188); in dvb_net_ule()
862 h.new_ts = 1; in dvb_net_ule()
863 h.ts += TS_SZ; in dvb_net_ule()
864 h.priv->ts_count++; in dvb_net_ule()
865 if (h.priv->ule_skb == NULL) { in dvb_net_ule()
866 h.priv->need_pusi = 1; in dvb_net_ule()
867 h.priv->ule_sndu_type_1 = 0; in dvb_net_ule()
868 h.priv->ule_sndu_len = 0; in dvb_net_ule()